avatarTim Ward, Mature Flâneur

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>

Mature Flâneur

The Oldest Street Art in the World

Street art existed before there were streets!

First ever drawing of a person on skis, around 3000 BC. The moose is also pretty cool. All photos by Tim Ward.

This month Globetrotters Medium publication celebrates and explores Street Art…but just how old is this art form? I’ve got two contributions to make from different ends of Europe on this subject, and I welcome any comments on where else prehistoric street art might be found. First, how do you define street art in a era before streets? Well, simply, it has to be outdoors, and created in an area that plausibly had some foot traffic — a reason for stone-age men and women to saunter round for a look.

Alta, Norway

Alta is also one of the oldest inhabited places in Northern Europe. People first found their way to this fjord more than 7,000 years ago as the glaciers of the last Ice Age began to recede and the climate became more temperate. In fact, it was even warmer back then than it is today. The intrepid prehistoric people who lived in the far north left evidence of settlements, arrowheads, stone tools, and, above all, carvings etched on the rocky coast of Altafjord: beautiful, mysterious, graceful works of art chiselled in stone between 7,000 and 2,000 years ago.

Site of the Altafjord rock carvings

Six thousand figures have been discovered so far at the end of Altafjord, with more being uncovered every month beneath layers of moss and lichen. The greatest concentration of them, about 3,000 etchings, are in an open air museum on the outskirts of town. In 1985 they were recognized as a UNESCO World Heritage Site. Walking among them on the wooden pathway was simply mind-blowing.

Reindeer being driven into an enclosure.

The most common motifs on the rocks are of animals, especially reindeer, the most numerous large mammal in the Arctic. Some carvings depict methods of hunting still used by the indigenous Sami people until modern times, such as driving reindeer into an enclosure (above), or chasing them in boats into the paths of waiting hunters (below):

The bear is also a popular figure. One rock depicts a mother bear with cubs, her footprints leading back to a cave. Another shows a bear next to what appears to be a flounder at the end of a fishing line that drops from a boat. Is this some kind of spirit bear aiding the fisherman — or a simple visual aid, telling the story of landing a halibut as big as a bear! We will never know (note: halibut do grow this large in the Arctic waters).

What became obvious to Teresa (my wife) and me as we walked among the rocks is that these etched figures are not simply static images. They tell stories. Perhaps on a sunny afternoon in 5,000 BCE, one would saunter on down to the carvings and listen to one of the elders point to the bear, and tell the tale of the hunt.

By encoding stories on stone, these ancient people found a way to share their practical wisdom and memorable events in a way that could be transmitted from generation to generation. Perhaps their wall art that was also their Internet.

Coa Valley, Portugal

Though I was astounded by how ancient the prehistoric wall art of Norway was, the prehistoric Portuguese beat them by some 15,000 years! The Coa Valley Archeological Park in the remote northeast fringe of Portugal has over 5,000 prehistoric rock etchings between 22,000–20,000 years old!

Deer from the Coa Valley Archeological Park

An early UNESCO report on the park described it as “the biggest open-air site of paleolithic art in Europe, if not in the world.” Usually, we think of paleolithic art as cave paintings (which would not qualify it as street art!). But the Coa drawings are out in the open, spread over 23 sites along the Coa and Douro River valleys. How did they survive the elements? The drawings are not painted, they are line drawings carved directly into the stone.

The art may be prehistoric, but it is not primitive. These artists had talent. Like their Norwegian counterparts, they brought to life the animals crucial to their survival — deer, horses, wild goats, aurochs (large prehistoric cattle), and also human figures. These etchings provide an amazing glimpse of how prehistoric people saw their world and themselves. As UNESCO says of these “World Heritage Site” drawings:

Dating from the Upper Palaeolithic to the final Magdalenian/ Epipalaeolithic (22.000–8.000 BCE), [the drawings] represent a unique example of the first manifestations of human symbolic creation and of the beginnings of cultural development….The rock art…throws an exceptionally illuminating light on the social, economic, and spiritual life of our early ancestors.

Well, isnt’ that exactly what street art does today?

What is disappointing about the Coa carvings is that their makers etched new figures right on top of the old ones. Individually, the drawings may have been masterpieces, but when you see the raw rocks of Coa, they often look like jumbles of squiggles:

Copy of a typical etched stone from Coa Valley with many overlapping drawings.

Fortunately, the museum next to the Coa site has state-of-the-art technical innovations that bring the prehistoric drawings to life. The exhibit isolates the individual drawings that overlap on the rocks so that you can see each of their outlines clearly. Sometimes the outlines are projected right onto replicas of the original rocks so that the art seems to pop right out. In one case, they even animate some of the figures: you see the etched outline of a wild goat and then it springs to life, jumping and prancing across the rock as if frolicking on a cliffside.

Illuminating the figures brings the Coa Drawings to life.

The museum also highlighted some of the artistry involved. In several cases, there were animals that appeared to have two heads — but were in fact one animal with its head turned first in one direction and then in another, as if to portray the animal in motion — an artistic technique once thought to have been invented by that Cubist late-comer, Picasso!

Animals definitely dominated these artistic landscapes, which makes experts and flanêurs alike wonder, why? Did animals have a significant spiritual meaning? Was it simply pragmatic information about prey species that was being recorded (There are virtually no predators on the walls, except a few birds of prey.) Or was this art for art’s sake? The museum lays out several theories but wisely takes no sides.

The rare human figures from the Paleolithic period are mysterious and strange. The face on one figure looks absolutely as if Picasso drew it (below right). Two other figures are so explicitly phallic one has to wonder if this is evidence that men have been exaggerating their manhood since prehistoric times. Or, perhaps, more poetically, one could assume the artists were making symbolic connections between big penises and fecundity? Or, it might simply be that the rock artists of Coa started a trend that continues in the street art of today. Next time you see a penis spray-painted on a wall in an alleyway of a dirty city street, don't be offended! You are viewing one of the oldest artistic traditions of hunankind.

Left and middle: The world’s first dick pics. Right: Clearly Picasso stole everything from the Stone Age.

In sum, street art has been around for at least 20,000 years. As long as there are flat surfaces on which to scratch and paint, I suppose men and women will be inspired to create street art.

***

I’ve been inspired by so many of my fellow Globetrotters this month, especially this street art story from Jillian Amatt - Artistic Voyages on the town of Lacombe, Alberta’s mural capital:

Catherine Duchesne has contributed a thoughtful and provocative piece about the purpose of art itself, and how here encounters with street murals have helped her reflect more deeply on this question:

***

Good news! My new book, Mature Flâneur: Slow Travel through Portugal, France, Italy and Norway is now available! Check it out here:

Street Art
Travel
Monthly Challenge
Portugal
Norway
Recommended from ReadMedium