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>
Introducing Personal Data Exchanges & the Personal Data Economy
The next big technological shift is to a world where every individual can manage and (optionally) monetise their personal data.
Get in on the next big thing: Personal Data Exchanges. Image courtesy Tuesday Tech Tip
Companies like Facebook and Google already make billions because they know everything about us via our online habits. What if we could take a cut? What if we could own and sell our data directly?
Our personal data is an economic asset generated by a combination of our identity (demographics), our behaviour (psychographics— our interests, attitudes, and opinions) and our purchases (the lifestyle we lead based on what we vote for with our hard-earned income).
This asset is commonly traded for perceived higher value services and products. Examples are:
Being able to find information quickly online (Google);
Being able to share personal memories with friends and families (Facebook);
Being able to network with business colleagues and prospects (LinkedIn);
Being able to pay for purchases without carrying cash (Visa, MasterCard, et al).
If this hot-potato topic of data ownership and ‘privacy’ is new to you, here’s a quick primer on who owns your data, courtesy of Hub-of-All-Things:
Bottom line:
Platforms often know more about us than we know about us.
As bleak as this may sound, there is a shift underway:
From data owned, controlled and sold by companies
To data owned, controlled and sold by the individuals who generate the data.
Here’s what Giovanni Buttarelli, the European Data Protection Supervisor, has said about personal data:
“Our online lives currently operate in a provider-centric system, where privacy policies tend to serve the interests of the provider or of a third party, rather than the individual. Using the data they collect, advertising networks, social network providers and other corporate actors are able to build increasingly complete individual profiles. This makes it difficult for individuals to exercise their rights or manage their personal data online. A more human-centric approach is needed, which empowers individuals to control how their personal data is collected and shared.” — Giovanni Buttarelli, European Data Protection Supervisor, October 2016
The more human-centric approach Buttarelli refers to is currently being birthed, thanks to Personal Data Exchanges.
But what exactly is a Personal Data Exchange?
“A Personal Data Exchange (PDE) is a technology platform that enables individuals to own their personal data, manage their privacy and optionally monetise some or all of their digital DNA. PDE’s power the rapidly-emerging Personal Data Economy, where users — rather than platforms — benefit from User Generated Content and Data.”
Essentially, a PDE shifts control of personal data from the platform to the person. Its about letting individuals take ownership of their information so they can share it on their terms.
Contrary to popular belief, consumers (especially the younger generation) are no longer concerned about preserving their privacy. They are instead thinking about who has, and who should profit from their data, and how they can take back control, or even use their personal data to make life easier via a PDE. Makers, founders, disruptors and innovators are meeting this need by building platforms that empower users to control their data.
Examples of Personal Data Exchanges
I’ve been involved in the PDE space since 2013 and I’ve advised and consulted with 5 startups building products that can be described as PDE’s (an as-yet unnamed industry). Based on the interviews and research my team and I have conducted, here is a list of current Personal Data Exchanges. If you know of any others, please let me know.
CitizenMe: Founded in July 2013 by StJohn Deakins. A personal information management service which empowers digital citizens with their personal data. Collect personal data and apply AI to create personal insights. Team, Funding, Twitter.
Cozy: Founded in November 2012 by Benjamin Andre, Cozy Cloud is a web application that helps users organize their digital information. Raised $6.03M in 2 rounds from 3 investors. Team, Funding, Twitter.
Datacoup: Founded in June 2012 by Matt Hogan, DataCoup offers a data exchange platform for consumers to aggregate and sell their own anonymous personal data. Raised $1.28M in 2 rounds. Team, Funding, Twitter.
DataWallet: Founded by Serafin Lion Engel and Daniel Hawthorne, DataWallet is a blockchain powered Personal Data Management Platform that puts people in charge of their data and empowers developers to bring to live the next generation of world-class applications. Team, Funding, Twitter, DataWallet.
Digi.me: Started in June 2009 as SocialSafe by Julian Ranger, rebranded to Digi.me in 2014. Stores and shares personal health and finance data with businesses in exchange for personalised offers and rewards. Launched industry-wide discussion forum Internet of Me in 2015. Raised $10.64M in 6 rounds from 8 investors. Team, Funding, Twitter.
GoodData: Allows people to sell their browsing data and donate the profit to good causes. Members are co-owners of the platform and the data they submit. The service is a browser plug-in which blocks third party trackers, pools and anonymises the data, before selling it. Team, Twitter.
HubofAllThings.com: Domain registered November 2012. The initiative of 6 UK universities: Cambridge, Edinburgh, Nottingham, Surrey, Warwick, West of England. Platform was created to trade and exchangepersonal data for services in a standardised and structured manner. Raised £54,839 via crowdfunding in April 2016. Twitter.
Intelez: Domain registered January 2016. Allows people to share minimally necessary personal information while fully protecting their identity and privacy. They neither have nor intend to have any association with or receive funding from any federal, state, local or foreign government or government agency. Twitter.
Mass Network: Conceptualised in March 2016 by Alexander Kuzmin, Mass provides a blockchain-based solution to the problems of online advertising, such as pop-ups and exploitative practices. Raised 332.148 BTC (about $338,000) in an ICO in December 2016. Team, Prospectus, Twitter.
Meeco: Founded in 2012 by Katryna Dow, Meeco is an online service that enables its users to manage life and their important digital relationships. Popularising the API-of-Me with Meeco Labs. Worth reading the founder’s manifesto. Team, Funding, Twitter.
MiData: A co-operative for owning and sharing health data for social good. Team.
OpenDNA.ai: Launched early 2016. Uses artificial intelligence, machine learning and natural language processing to build an accurate personality profile for each user. Raised $1.1M in 1 Round. Listed on the ASX in November 2016. Team, Funding, Twitter.
People.io: Founded October 2015 by Nicholas Oliver. Gives people ownership of their data to enable the next evolution of human connectivity. Raised an undisclosed amount in 2 rounds from 6 investors. Team, Funding, Twitter.
PI.exchange: Launched September 2017, founded by Quan Pham in Australia. An app that accumulates your data passively as you live your life. This data is then run through machine learning models to give you personalized insights. Team, Twitter.
Pillar Project: The Pillar concept was first conceived in 2009 in David Siegel’s book, Pull, which imagined personal data control returned to consumers and a singular, interconnected platform to manage all digital interactions. Team, Twitter, Foundation.
Sofiia.io: Launched May 2016 by Tracy Saville. Aims to redefine online personal relationships by building rich personal profiles, owned and controlled by the user. Team, Funding, Twitter.
SeccoAura.com: Founded 2015 by Chris Gledhill and Vicky Barton. Envisions a world where every person’s worth is the contents of their character, not the contents of their wallet. A proximity-based social discovery app where users create value tokens backed by their reputations. Raised undisclosed amount in 1 round. Team, Funding, Twitter.
In addition to the platforms mentioned, there is an initiative underway called the MyData declaration.
Who’s missing?
Please let me know of any others by posting a response.
Why is the rise of PDE’s important anyway?
Society is undergoing a shift from command and control to collaboration and co-opetition. PDE’s are a natural next step in humanity’s development. There is a rather vigorous debate going on around Universal Basic Income, and I see PDE’s potentially playing a role in determining what every individual receives, but that is a topic for another day.
Project 2030
You made it to the end! If you’re interested in helping us solve some of the planet’s grand challenges with our ambitious Project 2030, please check out the overview, and invite others to do the same.
Postcards from 2035
Have you come across Postcards from 2035? It’s a series of profoundly simple interlinking ideas describing life in a highly desirable society, where everything and everyone is advanced, happy, intelligent and problem-free. It’s a blueprint of the world we need to co-create. Here’s what that world could look like.