avatarTimothy Key

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

5070

Abstract

do that:</p><div id="2e8b"><pre>eventHandler<span class="hljs-selector-class">.Handle</span>(event1, <span class="hljs-built_in">ExampleMiddlewareFoo</span>(<span class="hljs-built_in">ExampleMiddlewareBar</span>(handle)))</pre></div><h1 id="a8a5">Managing Events with Handlers and Middleware</h1><p id="f869">Most articles I read explain how to use this design pattern; this one deals with implementing the internal logic. So let's start coding.</p><p id="35c4">The full code for this article can be found <a href="https://github.com/xNok/slack-go-demo-socketmode/blob/main/examples/middleware/main.go">here</a> to help you follow along.</p><h2 id="0f88">Designing events</h2><p id="b622">First, we are going to enumerate the list of events that our system can handle. The way we create enumeration in Go is a bit different than in other programming languages. In Go, we are going to use a set of constants sharing the same <code>type</code>. Here I define a type <code>EventType</code>that represents a string with the event's name.</p><div id="b181"><pre>// <span class="hljs-keyword">type</span> <span class="hljs-type">used </span>to enumerate events <span class="hljs-keyword">type</span> <span class="hljs-type">EventType </span>string</pre></div><div id="4817"><pre>const ( event1 EventType <span class="hljs-operator">=</span> <span class="hljs-string">"event1"</span> event2 EventType <span class="hljs-operator">=</span> <span class="hljs-string">"event2"</span> )</pre></div><p id="e041">Next, we define the event itself. In our example, the<code>Event</code> as a type which can be selected among the list of <code>EventType</code> created above.</p><div id="2bc9"><pre><span class="hljs-keyword">type</span> <span class="hljs-type">Event</span> struct { <span class="hljs-type">Type</span> <span class="hljs-type">EventType</span> <span class="hljs-type">Data</span> interface{} }</pre></div><h2 id="df6c">Create an event sender (for test purpose)</h2><p id="60aa">To test our system, we will need to create a small function to send events every 2s. Each<code>Event</code> is transmitted via a <a href="https://tour.golang.org/concurrency/2">channel</a> and, the <code>eventSender</code> below sends a random <code>Event</code> of type <code>event1</code> or <code>event2</code> to a channel.</p><blockquote id="53f3"><p><i>Channels are a type which you can send and receive values, they are great for communication among goroutines. In other words, there are perfect for sending and receive event through your application.</i></p></blockquote><div id="ffd1"><pre><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">eventSender</span><span class="hljs-params">(c <span class="hljs-keyword">chan</span> EventType)</span></span> {</pre></div><div id="7f57"><pre> for { // Send <span class="hljs-selector-tag">a</span> random event <span class="hljs-selector-tag">to</span> the channel rand<span class="hljs-selector-class">.Seed</span>(<span class="hljs-selector-tag">time</span><span class="hljs-selector-class">.Now</span>()<span class="hljs-selector-class">.Unix</span>()) events := []EventType{ event1, event2, } n := rand.<span class="hljs-built_in">Int</span>() % <span class="hljs-built_in">len</span>(events)</pre></div><div id="6101"><pre> c <- events[n] <span class="hljs-comment">// send event to channel</span></pre></div><div id="5285"><pre> // <span class="hljs-keyword">wait</span> a <span class="hljs-built_in">bit</span> <span class="hljs-built_in">time</span>.Sleep(<span class="hljs-number">2</span> * <span class="hljs-built_in">time</span>.Second) } }</pre></div><h2 id="000c">Handler and dispatcher</h2><p id="e562">We first need a struct to hold the list of events we want to listen to and which function to call whenever that event is transmitted. This struct also contains the channel used for communicating events.</p><div id="280d"><pre><span class="hljs-comment">// Create a struct to hold config</span> <span class="hljs-comment">// And simplify dependency injections</span> <span class="hljs-keyword">type</span> EventHandler <span class="hljs-keyword">struct</span> { <span class="hljs-comment">// Event channel</span> Events <span class="hljs-keyword">chan</span> Event <span class="hljs-comment">// hold the registedred event functionss</span> EventMap <span class="hljs-keyword">map</span>[EventType][]<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(Event)</span></span> }</pre></div><p id="aa6c">Next, we need to provide an initializing constructor for our <code>EventHandler</code>.</p><div id="a4ed"><pre><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-title">NewEventHandler</span><span class="hljs-params">()</span></span> *EventHandler { eventMap := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">map</span>[EventType][]<span class="hljs-function"><span class="hljs-keyword">func</span><span class="hljs-params">(Event)</span></span>) event

Options

s := <span class="hljs-built_in">make</span>(<span class="hljs-keyword">chan</span> Event)</pre></div><div id="78bb"><pre> return <span class="hljs-variable">&</span>EventHandler<span class="hljs-punctuation">{</span> <span class="hljs-symbol"> Events:</span> events, <span class="hljs-symbol"> EventMap:</span> eventMap, <span class="hljs-punctuation">}</span> <span class="hljs-punctuation">}</span></pre></div><p id="98fe">Then, we can create our <code>Handle</code> function that associates the event with a callback function.</p><div id="308c"><pre><span class="hljs-comment">// register the handler function to handle an event type</span> func (h *EventHandler) <span class="hljs-built_in">Handle</span>(e EventType, f <span class="hljs-built_in">func</span>(Event)) { h<span class="hljs-selector-class">.EventMap</span><span class="hljs-selector-attr">[e]</span> = <span class="hljs-built_in">append</span>(h<span class="hljs-selector-class">.EventMap</span><span class="hljs-selector-attr">[e]</span>, f) }</pre></div><p id="e42a">Finally, we create the <code>EventDispatcher</code> function, the core of this mechanism. The <code>EventDispatcher</code>process any event sent to a channel, check its type, and if any function has been registering for that type, we call all registered functions.</p><div id="6597"><pre><span class="hljs-function"><span class="hljs-keyword">func</span> <span class="hljs-params">(h *EventHandler)</span></span> EventDispatcher() { <span class="hljs-keyword">for</span> evt := <span class="hljs-keyword">range</span> h.Events { log.Printf(<span class="hljs-string">"event recieved: %v"</span>, evt) <span class="hljs-keyword">if</span> handlers, ok := h.EventMap[evt.Type]; ok { <span class="hljs-comment">// If we registered an event</span> <span class="hljs-keyword">for</span> _, f := <span class="hljs-keyword">range</span> handlers { <span class="hljs-comment">// exacute function as goroutine</span> <span class="hljs-keyword">go</span> f(evt) } } } }</pre></div><h1 id="13e4">Using our system</h1><p id="4d4e">Everything is ready; we can start using our event handling system.</p><ol><li>Instantiate our event Handler</li><li>Register which event to listen to and what function to callback</li><li>Start the event sender</li><li>Start the event dispatcher</li></ol><div id="62ab"><pre><span class="hljs-keyword">func</span> <span class="hljs-title function_">main</span><span class="hljs-params">()</span> {</pre></div><div id="5b09"><pre> <span class="hljs-variable">eventHandler</span> := <span class="hljs-function"><span class="hljs-title">NewEventHandler</span>()</span></pre></div><div id="d244"><pre> eventHandler.Handle(event1, <span class="hljs-keyword">func</span><span class="hljs-params">()</span> { <span class="hljs-built_in">log</span>.Printf(<span class="hljs-string">"event Handled: %v"</span>, event1) })</pre></div><div id="5c56"><pre> <span class="hljs-variable">go</span> <span class="hljs-function"><span class="hljs-title">eventSender</span>(<span class="hljs-variable">eventHandler.Events</span>)</span></pre></div><div id="30f2"><pre> eventHandler<span class="hljs-selector-class">.EventDispatcher</span>()</pre></div><div id="9bf2"><pre>}</pre></div><p id="e590">The result should be along those lines:</p><figure id="5ee7"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*_D-GCRSu3K8CgTBXewJjJQ.gif"><figcaption></figcaption></figure><p id="19d6">Since we only handle an event of type <code>event1</code>, only <code>event1</code> shows as <code>Hansled</code>. All is good!</p><p id="d48a">The full code for this article can be found <a href="https://github.com/xNok/slack-go-demo-socketmode/blob/main/examples/middleware/main.go">here</a>.</p><h1 id="6f5e">Interesting Articles tackling the same topic</h1><ul><li><a href="https://drstearns.github.io/tutorials/gomiddleware/">Middleware Patterns in Go</a></li><li><a href="https://sathishvj.medium.com/web-handlers-and-middleware-in-golang-2706c2ecfb75">Web Handlers and Middleware in GoLang</a></li><li><a href="https://readmedium.com/lightweight-event-management-implemented-by-go-a654d59ac65">Lightweight event management implemented by Go</a></li><li><a href="https://readmedium.com/the-7-most-important-software-design-patterns-d60e546afb0e">The 7 Most Important Software Design Patterns</a></li></ul><p id="13e7"><i>Do you want <b>unlimited access</b> to all my content and many other writers’ content on Medium? Consider using my affiliate link to <a href="https://couedeloalexandre.medium.com/membership">become a Medium member today</a></i></p><h2 id="853a">Further reads</h2> <figure id="81d2"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://couedeloalexandre.medium.com/embed/list/3f9d03f2cb8f" allowfullscreen="" frameborder="0" height="184" width="undefined"> </div> </div> </figure></iframe></div></div></figure></article></body>

Writing | Inspiration

Stop and Reset

Even when you don’t feel motivated, there is still a lot you can do

Image by Larisa Koshkina from Pixabay

No matter how motivated we are generally, and even sometimes when we are on a roll at a specific point in time, sometimes you get hit with a case of the doldrums.

The doldrums are a state of being named after the intertropical convergence zone where the northerly winds meet southerly winds along the equator, and specifically a zone in the Atlantic where it is inordinately calm most of the time but peppered with occasional sudden storms.

An apt name for someone that was cooking along, but suddenly finds themselves adrift in an area with unpredictable and negligible winds.

So, what does one do in the doldrums? Not much. You can cast about listlessly and wish you could catch a break in the form of a sustained wind. You can despair and allow hopelessness to set in.

Or, you can accept the fact that it happens. Sometimes we just end up there. And you just have to make the best of it.

I am not going to shine you on. The first two options are the easiest to undertake; the first especially. But invariably, if you languish long enough, a certain amount of hopelessness tends to set in.

The best approach is to make use of your time. If you fancy yourself a writer, and the words aren’t coming, perhaps this is a good time to tackle all those peripheral tasks that you ignore when you are really in your writer’s stride.

Website

For instance, when is the last time you updated your website? Does it look like a MySpace page still? Might be time for a brand new fresh and bright look. At least scramble some of the segments around so it looks a bit different.

Mailing list

Looked through your list lately? Any culling or tidying up that needs to be done? Have you had your solicitation to join on autopilot? It might be time to freshen up that call to action.

Social Media

How about social media? How do you advertise across the social various social media platforms? Is it time to dive into Instagram or Pinterest if you don’t have accounts there? Fully social? Maybe it is time to refresh your look, change profile pictures or update contact information.

Business Plan

Do you have a business plan for your writing? It doesn’t have to be formal, or complex, but it is advantageous to have a written plan for your goals. In fact, it might be just a simple as that; a list of goals.

Once you have your list of goals, it is good to periodically check in and refresh and update your list. Maybe your plans have changed, or maybe you have hit some goals and it is time to make new ones — stretch yourself some more.

If you have up to date goals, it also might be time to add some initiatives to your business plan. How, specifically, are you going to accomplish your goals? Remember, this doesn’t have to be complex, but if you work on it over time you will soon have a great roadmap for your writing. Even if it is just for fun, you will want to have some benchmarks along the way.

Image by Pexels from Pixabay

Conclusion

This is not an exhaustive list, by any means. More of a springboard to get you (and me) thinking about how we can be proactive, even when we aren’t super motivated to write (or maybe do much of anything).

If nothing else, it would be a good exercise to make a list of all the peripheral activities that you do to support your writing. Maybe they include website maintenance, social media, mailing list updates or a business plan; maybe there are other things.

Sometimes just accomplishing something — anything — gives you that kick you need to get started back up in high-performance mode. If you made a list, then congratulations!

You just accomplished something!

If you like this, you might like some of my other writing:

Timothy Key spent over 26 years in the fire service as a firefighter/paramedic and various fire chief management roles. He firmly believes that bad managers destroy more than companies, and good managers create a passion that is contagious. Compassion, grace and gratitude drive the world; or at least they should. Follow me on Instagram, Facebook, and Twitter, and join the mail list.

Business
Inspiration
Leadership
Writing
Life Lessons
Recommended from ReadMedium