avatarBrian E. Wish, PhD

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>

Stereotyping My State

Photo by Enrique Macias on Unsplash

We don’t know a darn thing outside our bubbles

I’ve lived around the world and traveled to most corners of the United States. Everywhere I go, I learn something new about the people there. But visiting a place, or even living there for a year, is like going to an IMAX theater, putting in earplugs, and watching Dances With Wolves through a soda straw. You will get parts of the plot and maybe the gist of the movie, but not much subtlety or context.

We’re all guilty of making inferences based on limited information. I do it too. Something I read recently really brought it home.

A comments section touched a nerve. The main article slammed America as a crazed borderline fascist dystopia in an inescapable spiral of disease, decay, and collapse. Fine, I’m used to reading a certain amount of America-hating apocalypse porn. I’m numb.

A commentator, though, attacked my home state. The searing specificity got to me. Apparently, most Texans are pickup-driving gun-toting rednecks, and most of the pickups have “Shoot a Liberal” bumper stickers. If it was this way during the writer’s “hellish” visit back a few years ago, it must be even worse now.

One or two commentators replied with facts and figures about the state’s diversity. No matter, plenty of others supported the first because obviously Texas is a bastion of racism and discrimination. But Austin’s sorta OK.

If you’re nodding and agreeing, this article is aimed at you

The commentators have no conception of how to construct organically legitimate hybrid taxonomies. Because no such thing exists; I used the Academic B.S. Generator to come up with the phrase.

Anyhoo, the author of the comment presented a view of the sovereign state of Texas that is very real to him. I value that he shared his perspective. Rather than viewing it as insulting and dismissive of 29 million people, we need to examine how we think about places and their peoples. Too often we take our legitimate but tiny observations and expand them to characterize entire populations.

If men define situations as real, they are real in their consequences. — from The Child in America by W.I. Thomas and Dorothy Thomas

True or not, these stereotypes have very real consequences to the national dialogue. We can’t compromise or cooperate if we brand the other as evil, stupid, or racists based on limited experience, the acts of a few, or a funny meme.

Photo by Matthew T Rader on Unsplash

Let’s talk about Texas

Born and raised in Texas, I’ve never seen a “Shoot a Liberal” bumper sticker. Maybe there are a few hundred driving around out of the 22 million registered vehicles. So what?

What does offend me are the pickup trucks with a faux scrotum hanging on the trailer hitch. I see those maybe a couple of times a month out of the thousands of vehicles I see on the road. Eww. But it doesn’t rise to hellish, and I’m digressing.

Are there white supremacists? Sure, most states have a few nut-jobs out in the hinterlands. This is the state where Robert Byrd was dragged to death in 1998 out in Jasper. Did you know that Jasper is majority black? And had a black mayor at the time? And that the authorities called the FBI within 24 hours for help? And that two of the three perpetrators have been put to death? There’s also plenty of passive racism to go around, but that’s not unique either, is it?

Most people forget just how different someone’s life and experiences can be living on one side of a river or another, on one side of the tracks or the other, or even a few blocks away. You can’t know someone’s truth unless you’ve lived their life, and that’s very, very rare.

Jasper has 7,600 citizens, most of whom are fine Americans just trying to get along. It’s also not representative of how most Texans live.

Three of the ten largest cities in the United States, #4 Houston, #7 San Antonio, and #9 Dallas are in Texas. As a bonus, Austin and Fort Worth come in at #11 and #14, so five of the fifteen largest cities are in Texas. As of 2010, 84.7% of Texans lived in urban areas or urban clusters, compared to 87.9% for New York and 88.5% for Illinois.

Texas is also a majority-minority state. Consider San Antonio. Whites make up 72.6% of the city, but non-Hispanic whites are only 26.6%, and the overall Hispanic population is 63.2%. The city culture of San Antonio is very different from Houston or Dallas, which are different from Austin, which is different than Fort Worth.

Even in a metro area, you can’t generalize. If I tell you what we believe in the Dallas-Fort Worth area, am I speaking for the Indian and Korean communities in Irving? Or the Vietnamese in Arlington?

Heck, when I walk through my upper-middle-class neighborhood, I see black, middle-eastern, Indian, and Hispanic families. We all smile and wave at each other. I can’t generalize about my own subdivision.

Photo by Jan on Unsplash

Let’s talk New York

I’ve visited New York City twice in the last couple of years. Just walking around and looking at the people and the scenery taught me a lot. I visited tourist attractions, saw the Rockettes Christmas show, and generally did some touristy mid-town Manhatten stuff.

Being somewhere is different than seeing it on television. You get a new and better perspective. But you are still a tourist.

Every restaurant I went to was great…the Indian restaurant, the brew-pub, the upscale burger place, the cheap walk-up pizza place on a cold day, and especially the Korean barbeque in K-town. I conclude that New York City has the best food in the world! Or, maybe this just means I’ve learned to use Yelp when traveling. All I can conclude is that good food isn’t hard to find and there’s a lot of variety.

Of the dozen New Yorkers I talked to, which one represents what New Yorkers think? Maybe I should listen to the Ukrainian Uber driver that lectured us on immigration and ranted against the “…F__ing redneck drivers from New Jersey!” I visited New York and it’s full of Trump-supporting Ukrainians!

Maybe I should judge New York by the shaggy born-again preacher that pushed into our standing room only subway car at the last minute and proceeded to spread Jesus? Hallelujah, there are believers in New York City! It’s a movement and they are all going to be SAVED!

If I generalize about New York City, am I including the fifty-something son of Dominican immigrants that grew up in Washington Heights in the ’80s and the twenty-something trust fund baby from Tribeca? I have some data to say that neither likely voted for Trump, but otherwise, age and experiences might have brought them to very different places.

I had thought I was an expert after six seasons of Sex in the City and watching the Godfather twice. Thank goodness I got a couple of weekends under my belt; I’m now twice the expert that I was.

2 X .00001 = .00002

Photo by Kyle Glenn on Unsplash

Let’s talk the world

I lived in northeast Italy for two and a half years in the ’90s. They like their own food; it was hard to find a restaurant serving another country’s fare. Dinner can be a multi-hour event. They like their coffee. I had friends that dated Italians, and I was friendly with a lot of the locals working on the airbase.

Do I know Italy? No. There were plenty of cultural cues that I would have missed if I hadn’t spent time hanging out with an Italian-American friend from Florida who spent his summers in Italy growing up. I only visited Rome once, and never made it further south. I compared notes with my brother who had lived on La Maddalena off the coast of Sardinia a few years earlier. Some things we agreed upon, and on others we came away with completely different impressions. We are probably both wrong.

I spent over a year in Korea. Again, I learned a lot more about the country than anyone who’s never visited. Koreans point with their middle finger, but it’s just a finger. A lot of the Koreans I met had an…aggressive…approach to alcohol. Can I generalize that Koreans are all heavy drinkers? No! I have no idea how much soju the average Korean couple drink at home with dinner with the kids.

I’ve been to Germany half a dozen times. What’s the real Germany? Was it Oktoberfest in Munich? If so, was it the Hofbrau tent or the Paulaner tent? Or is the real Germany the small village where one of my friends lived? All the neighbors know each other and they have regular cookouts. Or is Germany the beautiful day I spent by myself wandering around Heidelburg? I need to generalize, dammit!

Every place I’ve been to, it’s the same story. The city, state, or country is not what I expect, and I don’t understand until I see it with my own eyes. Then, I meet some locals and find out that I didn’t understand what I was seeing.

Brian E. Wish works as a quality engineer in the aerospace industry. He has spent 29 years active and reserve in the US Air Force, where he holds the rank of Colonel. He has a bachelor’s from the US Air Force Academy, a master’s from Bowie State, and a Ph.D. in Public and Urban Administration from UT Arlington. The opinions expressed here are his own. Learn more at brianewish.com.

Society
Culture
Politics
Equality
Humor
Recommended from ReadMedium