<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mustafa Turan</title>
    <description>The latest articles on DEV Community by Mustafa Turan (@mustafaturan).</description>
    <link>https://dev.to/mustafaturan</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F85093%2F0d3867e4-dbec-4c2a-9cef-30fb17bcb430.jpeg</url>
      <title>DEV Community: Mustafa Turan</title>
      <link>https://dev.to/mustafaturan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mustafaturan"/>
    <language>en</language>
    <item>
      <title>Zero Dependency Open Source</title>
      <dc:creator>Mustafa Turan</dc:creator>
      <pubDate>Thu, 02 May 2019 07:29:01 +0000</pubDate>
      <link>https://dev.to/mustafaturan/zero-dependency-open-source-o7g</link>
      <guid>https://dev.to/mustafaturan/zero-dependency-open-source-o7g</guid>
      <description>&lt;p&gt;Writing a zero-dependency open-source library could be the way to bring an immortal contribution to the developer communities. Adding dependencies to your open-source will bring many update/upgrade work while your busy life goes on. And you/community may give-up one day to update those dependencies because of several reasons. Even the zero-dependency library might need language version updates. So, the real intention is keeping as minimum dependency as possible. &lt;/p&gt;




&lt;p&gt;Instead of putting dependencies, put interfaces to the library and let the library users to use their own choice of libraries by implementing your interface. And share sample implementations with a dependent library as an example instead of directly adding implementation. (What is being defined is also a part of hexagonal-architecture pattern for software design which makes the library optioned without implementation choices.) &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 steps to provide zero-dependency library:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Implement your library functionality&lt;/li&gt;
&lt;li&gt;When you need an external dependency(external library from another author), create an interface instead of adding the dependency&lt;/li&gt;
&lt;li&gt;Document a sample implementation with/without dependency (but do not implement)&lt;/li&gt;
&lt;li&gt;Let the library user decide what to use &amp;amp; leave the interface implementation to the library user. &lt;/li&gt;
&lt;/ol&gt;




&lt;p&gt;This could be the way to bring an immortal contribution to the developer communities. Since there will be no dependency, the library can be used for new projects/libraries with different implementation details. Even after years, new implementations would be possible without updating the library...&lt;/p&gt;

&lt;p&gt;Before taking action, it is highly recommended also reading &lt;a href="https://dhh.dk/2012/rails-is-omakase.html"&gt;DHH's Rails is Omakase&lt;/a&gt; post. More ideas are highly welcome. Let's discuss.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Decoupled Package Communication in Go</title>
      <dc:creator>Mustafa Turan</dc:creator>
      <pubDate>Sun, 28 Apr 2019 23:14:24 +0000</pubDate>
      <link>https://dev.to/mustafaturan/decoupled-package-communication-in-go-g39</link>
      <guid>https://dev.to/mustafaturan/decoupled-package-communication-in-go-g39</guid>
      <description>&lt;p&gt;Go is very powerful language for software development with its simplicity, concurrency, first-class functions and tools. &lt;/p&gt;

&lt;p&gt;In Go, usually, a package is responsible only for one thing. Applications grows with several packages with their own responsibilities. When the number of packages in the project and responsibilities of the project increase, it is possible to mess up on communication with other packages. (In here, the communication means calling functions on different packages/modules on the flow with/without waiting result. Like incrementing counter metric when an order received/full-filled)&lt;/p&gt;




&lt;p&gt;One of the known ways of decoupling on communication is the event driven software designs. Usually, using an external event/message-bus server is the way distributing the responsibility to internal/external services. But this also brings another external component to your stack. And each stack comes with its own problems. &lt;/p&gt;

&lt;p&gt;For small services, packages/libraries, and embedded systems adding an external bus could be unnecessary addition. To overcome this problem, adding an internal message-bus package to your package may help. And when things getting bigger, it is possible to communicate with this internal message-bus to external message-bus services.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawa9905696zi1go0fj80.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fawa9905696zi1go0fj80.png" alt="event bus"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Assume that, a project needs to do several things on user registration like; incrementing counters, sending email, logging, and/or sending webhook to external service; instead of directly calling each of the functionalities directly, a message-bus can help to execute multiple functionalities asynchronously without knowing the caller.&lt;/p&gt;




&lt;p&gt;Decoupled packages help us to write cleaner code, focus on only one thing at a time. With &lt;a href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;bus&lt;/a&gt; Go package, you can get benefit of real message bus system and write decoupled packages easily. The &lt;code&gt;bus&lt;/code&gt; package allows any handler to listen any events, without knowing who generates the event. Thus, packages can communicate without depending on each other. Moreover, it is very easy to substitute a consumer function. As long as the new function understands the &lt;code&gt;Event&lt;/code&gt; struct that are being sent and received, the other functions will never know.&lt;/p&gt;




&lt;h3&gt;
  
  
  Get Started With &lt;code&gt;Bus&lt;/code&gt; Go Package in 4 Steps
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Configure
&lt;/h4&gt;

&lt;p&gt;The &lt;a href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;&lt;code&gt;bus&lt;/code&gt;&lt;/a&gt; package requires a unique id generator to assign ids to events. You can write your own function to generate unique ids or use a package that provides unique id generation functionality. Here is a sample configuration using monoton id generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/mustafaturan/bus"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/mustafaturan/monoton"&lt;/span&gt;
    &lt;span class="s"&gt;"github.com/mustafaturan/monoton/sequencer"&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// configure id generator (it doesn't have to be monoton)&lt;/span&gt;
    &lt;span class="n"&gt;node&lt;/span&gt;        &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;initialTime&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="kt"&gt;uint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;monoton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sequencer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;NewMillisecond&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;initialTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;// configure bus&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Configure&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Config&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="n"&gt;monoton&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;});&lt;/span&gt; &lt;span class="n"&gt;err&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="no"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nb"&gt;panic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"whoops"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Register Event Topics
&lt;/h4&gt;

&lt;p&gt;To emit events to the topics, topic names need to be registered first:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="k"&gt;func&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
    &lt;span class="c"&gt;// register topics&lt;/span&gt;
    &lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterTopics&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"order.received"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;"order.fulfilled"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c"&gt;// ...&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Register Event Handlers
&lt;/h4&gt;

&lt;p&gt;To receive topic events you need to register handlers; A handler basically requires two values which are a &lt;code&gt;Handle&lt;/code&gt; function and topic &lt;code&gt;Matcher&lt;/code&gt; &lt;em&gt;regex pattern&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Handle&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;func&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;){&lt;/span&gt; 
        &lt;span class="c"&gt;// fmt.Printf("Event: %+v %+v\n", e, e.Topic)&lt;/span&gt;
        &lt;span class="c"&gt;// do something&lt;/span&gt;
        &lt;span class="c"&gt;// NOTE: Highly recommended to process the event in an async way&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="n"&gt;Matcher&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s"&gt;".*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c"&gt;// regex pattern that matches all topics&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RegisterHandler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"a unique key for the handler"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h4&gt;
  
  
  Emitting Events
&lt;/h4&gt;

&lt;p&gt;The &lt;code&gt;bus&lt;/code&gt; package provides a generic event struct to standardize what an event is for all of its handlers. Before delivering an event, it is good to know what an event is for the &lt;a href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;&lt;code&gt;bus&lt;/code&gt;&lt;/a&gt; package. If this is your fist moments with the library, it is highly recommended to check the data structure of the &lt;a href="https://godoc.org/github.com/mustafaturan/bus#Event" rel="noopener noreferrer"&gt;&lt;code&gt;Event&lt;/code&gt;&lt;/a&gt; struct.&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight go"&gt;&lt;code&gt;&lt;span class="n"&gt;txID&lt;/span&gt;  &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"some-transaction-id-if-exists"&lt;/span&gt; &lt;span class="c"&gt;// if it is blank, bus will generate one&lt;/span&gt;
&lt;span class="n"&gt;topic&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="s"&gt;"order.received"&lt;/span&gt;                &lt;span class="c"&gt;// event topic name (must be registered before)&lt;/span&gt;
&lt;span class="n"&gt;order&lt;/span&gt; &lt;span class="o"&gt;:=&lt;/span&gt; &lt;span class="nb"&gt;make&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;map&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;         &lt;span class="c"&gt;// interface{} data for event&lt;/span&gt;

&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"orderID"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;     &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"123456"&lt;/span&gt;
&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"orderAmount"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"112.20"&lt;/span&gt;
&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"currency"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;    &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"USD"&lt;/span&gt;

&lt;span class="n"&gt;bus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Emit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;txID&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c"&gt;// emit the event for the topic&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Congratulations!!! You emitted your first event with the &lt;code&gt;bus&lt;/code&gt; package. Now, the all matched handlers will receive the same event. Please try yourself and share your experience as comment. &lt;/p&gt;

&lt;p&gt;Also a &lt;strong&gt;sample project&lt;/strong&gt; using &lt;a href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;&lt;code&gt;bus&lt;/code&gt;&lt;/a&gt; package can be found on &lt;a href="https://github.com/mustafaturan/bus-sample-project" rel="noopener noreferrer"&gt;bus-sample-project Github&lt;/a&gt;.&lt;/p&gt;




&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev.to%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/mustafaturan" rel="noopener noreferrer"&gt;
        mustafaturan
      &lt;/a&gt; / &lt;a href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;
        bus
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      🔊Minimalist message bus implementation for internal communication with zero-allocation magic on Emit
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🔊 Bus&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://godoc.org/github.com/mustafaturan/bus" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/16d1db6f25b18596e00fc985058fba80651eda5888ae9c727e858a0a1b6f5fd0/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f6d757374616661747572616e2f6275733f7374617475732e737667" alt="GoDoc"&gt;&lt;/a&gt;
&lt;a href="https://travis-ci.org/mustafaturan/bus" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/29c54f33a486b768cb41b75ad5962aabe5d0b6d3728f4de9d7962b57af68d0fd/68747470733a2f2f7472617669732d63692e6f72672f6d757374616661747572616e2f6275732e7376673f6272616e63683d6d61696e" alt="Build Status"&gt;&lt;/a&gt;
&lt;a href="https://coveralls.io/github/mustafaturan/bus?branch=main" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/537774c3c43f44bf9d436bf48da4a1cb4b663b258a90282ef5162637364e5485/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f6d757374616661747572616e2f6275732f62616467652e7376673f6272616e63683d6d61696e" alt="Coverage Status"&gt;&lt;/a&gt;
&lt;a href="https://goreportcard.com/report/github.com/mustafaturan/bus" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/87ca88c8f7288613f3cfee04fb1450b1adf009f4706a6247a8b55a84b95fde5d/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6d757374616661747572616e2f627573" alt="Go Report Card"&gt;&lt;/a&gt;
&lt;a href="https://github.com/mustafaturan/bus/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/cb5e8d0e620413e6b76e6fe7fda054afda903498d96b2ec31fc2a42c6ede4d95/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6d757374616661747572616e2f6275732e737667" alt="GitHub license"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bus is a minimalist event/message bus implementation for internal communication
It is heavily inspired from my &lt;a href="https://github.com/otobus/event_bus" rel="noopener noreferrer"&gt;event_bus&lt;/a&gt;
package for Elixir language.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;API&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;The method names and arities/args are stable now. No change should be expected
on the package for the version &lt;code&gt;3.x.x&lt;/code&gt; except any bug fixes.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Installation&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Via go packages:
&lt;code&gt;go get github.com/mustafaturan/bus/v3&lt;/code&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Usage&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Configure&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;The package requires a unique id generator to assign ids to events. You can
write your own function to generate unique ids or use a package that provides
unique id generation functionality.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;bus&lt;/code&gt; package respect to software design choice of the packages/projects. It
supports both singleton and dependency injection to init a &lt;code&gt;bus&lt;/code&gt; instance.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Hint:&lt;/em&gt;
Check the &lt;a href="https://github.com/mustafaturan/bus-sample-project" rel="noopener noreferrer"&gt;demo project&lt;/a&gt; for
the singleton configuration.&lt;/p&gt;
&lt;p&gt;Here is a sample initilization using &lt;code&gt;monoton&lt;/code&gt; id generator:&lt;/p&gt;
&lt;div class="highlight highlight-source-go notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; (
    &lt;span class="pl-s"&gt;"github.com/mustafaturan/bus/v3"&lt;/span&gt;
    &lt;span class="pl-s"&gt;"github.com/mustafaturan/monoton/v2"&lt;/span&gt;
    &lt;span class="pl-s"&gt;"github.com/mustafaturan/monoton/v2/sequencer"&lt;/span&gt;
)
&lt;span class="pl-k"&gt;func&lt;/span&gt; &lt;span class="pl-en"&gt;NewBus&lt;/span&gt;() &lt;span class="pl-c1"&gt;*&lt;/span&gt;bus.&lt;span class="pl-smi"&gt;Bus&lt;/span&gt; {
    &lt;span class="pl-c"&gt;// configure id generator (it doesn't have&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/mustafaturan/bus" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>go</category>
      <category>pubsub</category>
      <category>eventbus</category>
      <category>messagebus</category>
    </item>
    <item>
      <title>Persisting event data to Postgres using GenStage and EventBus</title>
      <dc:creator>Mustafa Turan</dc:creator>
      <pubDate>Tue, 31 Jul 2018 08:10:52 +0000</pubDate>
      <link>https://dev.to/mustafaturan/persisting-event-data-to-postgres-using-genstage-and-eventbus-oi9</link>
      <guid>https://dev.to/mustafaturan/persisting-event-data-to-postgres-using-genstage-and-eventbus-oi9</guid>
      <description>&lt;p&gt;One of the ways to consume EventBus events is implementing GenStage consumers. GenStage handles backpressure easily with configurable workers. &lt;code&gt;event_bus_postgres&lt;/code&gt; library uses GenStage to persist &lt;code&gt;event_bus&lt;/code&gt; events to postgres DB with batch insert.&lt;/p&gt;

&lt;h4&gt;
  
  
  How it works
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;+-----+
|     |                                         GEN STAGE
|     |        EVENTBUS      +------------------------------------------+
|     |        CONSUMER      |                   +---+                  |
|     |        +-----+       |                   |   |                  |
|     |        |     |       |                   |   |          +---+   |
|     |        |  E  |       |                   |   |          |   |   |
|     |        |  v  |       |                   |   |          |   |   |
|     |        |  e  |       |                   |   |          |   |   |
|  E  |        |  n  |       |                   | E |          |   |   |
|  l  |        |  t  |       |  +-------+        | v |          |   |   |
|  i  | topic  |  B  |  topic   |       |        | e |          |   |
|  x  |   +    |  u  |    +     |   Q   |        | n |          | B |       +--+
|  i  |event_id|  s  | event_id |   u   |   ask  | t |    ask   | u |       |  |
|  r  |-------&amp;gt;|  .  |---------&amp;gt;|   e   |&amp;lt;-------|   | &amp;lt;--------| c | BATCH |  |
|     |        |  P  |          |   u   |-------&amp;gt;| M | --------&amp;gt;| k |------&amp;gt;|DB|
|  E  |        |  o  |          |   e   |   pull | a |    pull  | e | INSERT|  |
|  v  |        |  s  |          |       |        | p |          | t |       |  |
|  e  |        |  t  |       |  +-------+        | p |          |   |   |   +--+
|  n  |        |  g  |       |  GENSTAGE         | e |          |   |   |
|  t  |        |  r  |       |  PRODUCER         | r |          |   |   |
|  B  |        |  e  |       |                   |   |          |   |   |
|  u  |        |  s  |       |                   |   |          |   |   |
|  s  |        +-----+       |                   |   |          |   |   |
|     |&amp;lt;-----------------------------------------|   |          +---+   |
|     |                      |    fetch_event/1  |   |         CONSUMER |
|     |                      |                   |   |                  |
+-----+                      |                   +---+                  |
                             |                  CONSUMER                |
                             |                  PRODUCER                |
                             +------------------------------------------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Components
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;EventBus&lt;/strong&gt;&lt;br&gt;
Message bus for Elixir; it publishes &lt;code&gt;event_id&lt;/code&gt; and &lt;code&gt;topic&lt;/code&gt; data to &lt;code&gt;topic&lt;/code&gt; subscribers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EventBus.Postgres&lt;/strong&gt;&lt;br&gt;
Message bus event consumer; it pushes &lt;code&gt;event_id&lt;/code&gt; and &lt;code&gt;topic&lt;/code&gt; to the &lt;code&gt;EventBus.Postgres.Queue&lt;/code&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Queue&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;GenStage&lt;/code&gt; producer; it is a simple queue implementaion&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;EventMapper&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;GenStage&lt;/code&gt; producer-consumer; it pulls/dequeues from &lt;code&gt;EventBus.Postgres.Queue&lt;/code&gt;, and fetch original event from &lt;code&gt;EventBus&lt;/code&gt; and then convert data into &lt;code&gt;Ecto&lt;/code&gt; model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bucket&lt;/strong&gt;&lt;br&gt;
&lt;code&gt;GenStage&lt;/code&gt; consumer; it pulls/dequeues from &lt;code&gt;EventBus.Postgres.EventMapper&lt;/code&gt; and batch insert data to Postgres DB.&lt;/p&gt;

&lt;p&gt;Source code: &lt;a href="https://github.com/otobus/event_bus_postgres"&gt;https://github.com/otobus/event_bus_postgres&lt;/a&gt;&lt;/p&gt;

</description>
      <category>genstage</category>
      <category>eventbus</category>
      <category>elixir</category>
      <category>postgres</category>
    </item>
    <item>
      <title>Decoupled Modules with Elixir EventBus</title>
      <dc:creator>Mustafa Turan</dc:creator>
      <pubDate>Mon, 23 Jul 2018 07:48:41 +0000</pubDate>
      <link>https://dev.to/mustafaturan/decoupled-modules-with-elixireventbus-4fcd</link>
      <guid>https://dev.to/mustafaturan/decoupled-modules-with-elixireventbus-4fcd</guid>
      <description>&lt;p&gt;Elixir EventBus is a library that allows different modules to communicate with each other without knowing about each other. A module/function can create an Event struct, and deliver to the EventBus without knowing which modules will consume.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--v-ESyvbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dofuyx6s747owdpaf9im.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--v-ESyvbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/dofuyx6s747owdpaf9im.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Modules can also listen to events on the EventBus, without knowing who sent the events. Thus, modules can communicate without depending on each other. Moreover, it is very easy to substitute a consumer module. As long as the new module understands the &lt;code&gt;Event&lt;/code&gt; struct that is being sent and received, the other modules will never know.&lt;/p&gt;




&lt;h3&gt;
  
  
  Get started with decoupled modules in 4 steps
&lt;/h3&gt;

&lt;p&gt;Decoupled modules help us to write clear code, focus on only one thing at a time. With EventBus library, you can get benefit of real event bus system and write decoupled modules easily.&lt;/p&gt;

&lt;h4&gt;
  
  
  Registering event topics
&lt;/h4&gt;

&lt;p&gt;On your app init, or anytime before delivering the events we need to register our topics. For example, when we receive a payment, we will create &lt;code&gt;checkout_completed&lt;/code&gt; event.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_topic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:checkout_completed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;register_topic&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:checkout_failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Delivering events
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;EventBus.EventSource&lt;/code&gt; module provides notify helper to deliver events without modifying your current code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;Order&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;EventSource&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;checkout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;event_params&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;%{&lt;/span&gt;&lt;span class="ss"&gt;topic:&lt;/span&gt; &lt;span class="ss"&gt;:checkout_completed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;error_topic:&lt;/span&gt; &lt;span class="ss"&gt;:checkout_failed&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="no"&gt;EventSource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;notify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event_params&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt; &lt;span class="c1"&gt;# process the payment as usual in here and if errors then return {:error, _} tuple&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Subscribing consumers to topics
&lt;/h4&gt;

&lt;p&gt;Assume that we have several operations waiting on success and failure conditions. Let's subscribe the consumers to the event topics.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="no"&gt;StockUpdateService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"^checkout_completed$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"^new_stock_arrived$"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;]})&lt;/span&gt;
&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="no"&gt;CargoService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"^checkout_completed$, "&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;cargo_dispatched&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s2"&gt;", "&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;new_stock_arrived&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s2"&gt;", ...]})
EventBus.subscribe({EmailService, ["&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;user_registered&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s2"&gt;", "&lt;/span&gt;&lt;span class="o"&gt;^&lt;/span&gt;&lt;span class="n"&gt;checkout_completed&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s2"&gt;", ...]})
EventBus.subscribe({EventBus.Logger, ["&lt;/span&gt;&lt;span class="o"&gt;.*&lt;/span&gt;&lt;span class="s2"&gt;"]})
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Consuming events
&lt;/h4&gt;

&lt;p&gt;EventBus consumers are just modules so they can be implemented by any kind of consumer strategy including GenStage(&lt;a href="https://github.com/otobus/event_bus_postgres"&gt;event_bus_postgres&lt;/a&gt; as sample), pooling, DynamicSupervisors, global consumers, spawn et al. So, depending on your use case, implement your consumers with the best suitable strategy. (But any kind of blocker strategies are not recommended!)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;CargoService&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="no"&gt;GenServer&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="no"&gt;GenServer&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;cast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;__MODULE__&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;event_shadow&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;handle_cast&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;payment_data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_event_data&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="c1"&gt;# do sth with payment_data&lt;/span&gt;
    &lt;span class="o"&gt;...&lt;/span&gt;
    &lt;span class="c1"&gt;# mark event as completed for this consumer&lt;/span&gt;
    &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_as_completed&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="no"&gt;CargoService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="ss"&gt;:noreply&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is another consumer that needs all event structure and consumes with spawning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="k"&gt;defmodule&lt;/span&gt; &lt;span class="no"&gt;StockUpdateService&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="n"&gt;process&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;     
      &lt;span class="n"&gt;event&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;fetch_event&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="c1"&gt;# do sth with event.data and/or any other event attributes&lt;/span&gt;
      &lt;span class="o"&gt;...&lt;/span&gt;
      &lt;span class="c1"&gt;# mark event as completed for this consumer&lt;/span&gt;
      &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;mark_as_completed&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="no"&gt;StockUpdateService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  About the EventBus library
&lt;/h3&gt;

&lt;p&gt;EventBus library is a traceable, extendible, fast, and memory friendly pure Elixir implementation without any external dependency in the pocket.&lt;/p&gt;

&lt;h4&gt;
  
  
  Traceable
&lt;/h4&gt;

&lt;p&gt;EventBus library comes with good optional attributes to provide traceability. When a consumer receive the topic and event_id, it can fetch structure with &lt;code&gt;fetch_event/1&lt;/code&gt; function. And if you use EventBus.EventSource helper, the optional fields are set automatically for you. Here is the structure of an Event model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="p"&gt;%&lt;/span&gt;&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;id:&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# required&lt;/span&gt;
  &lt;span class="ss"&gt;transaction_id:&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# optional&lt;/span&gt;
  &lt;span class="ss"&gt;topic:&lt;/span&gt; &lt;span class="n"&gt;atom&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# required&lt;/span&gt;
  &lt;span class="ss"&gt;data:&lt;/span&gt; &lt;span class="n"&gt;any&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# required,&lt;/span&gt;
  &lt;span class="ss"&gt;initialized_at:&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# optional&lt;/span&gt;
  &lt;span class="ss"&gt;occurred_at:&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# optional&lt;/span&gt;
  &lt;span class="ss"&gt;source:&lt;/span&gt; &lt;span class="no"&gt;String&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="c1"&gt;# optional&lt;/span&gt;
  &lt;span class="ss"&gt;ttl:&lt;/span&gt; &lt;span class="n"&gt;integer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;# optional&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Extendible
&lt;/h4&gt;

&lt;p&gt;EventBus library allows subscribing events with regex patterns, which allows consumers to subscribe new topics automatically. With this feature, it allows extending the system asynchronously with generic consumers like &lt;a href="https://github.com/otobus/event_bus_logger"&gt;event_bus_logger&lt;/a&gt;, &lt;a href="https://github.com/otobus/event_bus_postgres"&gt;generic Postgresql event store&lt;/a&gt;, &lt;a href="https://github.com/otobus/event_bus/wiki/EventBus-Metrics-and-UI"&gt;event_bus_metrics UI&lt;/a&gt;, and so on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bhevEvgZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9mldxd6atsm3hj1qeocm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bhevEvgZ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/9mldxd6atsm3hj1qeocm.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Fast by design
&lt;/h4&gt;

&lt;p&gt;EventBus library uses builtin memory store ETS effectively to get benefits of concurrent reads and writes. It doesn't block majority of the read operations, and allows concurrent reads to fetch Event data.&lt;/p&gt;

&lt;p&gt;It applies &lt;a href="https://www.vividcortex.com/resources/queueing-theory"&gt;queueing theory&lt;/a&gt; to handle inputs. And almost all implementation data accesses have O(1) complexity.&lt;/p&gt;

&lt;h4&gt;
  
  
  Memory friendly
&lt;/h4&gt;

&lt;p&gt;EventBus library delivers only topic and event_id to the consumers and keeps the original event data in the topic's Event table. So, only when consumers are able to process the event, then they fetch the event data.&lt;/p&gt;




&lt;h4&gt;
  
  
  Distributed?
&lt;/h4&gt;

&lt;p&gt;Even though the main intention to create this library is to use for internal module communications, it is possible to deliver events across nodes. One of the ways to delivery is sending message to connected other nodes as usual Elixir/Erlang way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight elixir"&gt;&lt;code&gt;&lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;-&lt;/span&gt; &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:register_topic&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:checkout_completed&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="no"&gt;Node&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:notify&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[%{&lt;/span&gt;&lt;span class="no"&gt;EventBus&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Model&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="no"&gt;Event&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;}}])&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Note: EventBus library is not in the same class distributed solutions like Apache Kafka, RabbitMQ, or Redis Streams.&lt;/p&gt;

&lt;p&gt;Original story on Medium: &lt;a href="https://medium.com/elixirlabs/decoupled-modules-with-elixir-eventbus-a709b1479411"&gt;https://medium.com/elixirlabs/decoupled-modules-with-elixir-eventbus-a709b1479411&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The source code of EventBus library: &lt;a href="https://github.com/otobus/event_bus"&gt;https://github.com/otobus/event_bus&lt;/a&gt;&lt;/p&gt;

</description>
      <category>elixir</category>
      <category>eventbus</category>
      <category>pubsub</category>
    </item>
    <item>
      <title>When to give a star to an open source library?</title>
      <dc:creator>Mustafa Turan</dc:creator>
      <pubDate>Tue, 17 Jul 2018 04:23:00 +0000</pubDate>
      <link>https://dev.to/mustafaturan/when-to-give-a-star-to-an-open-sourcelibrary-11a4</link>
      <guid>https://dev.to/mustafaturan/when-to-give-a-star-to-an-open-sourcelibrary-11a4</guid>
      <description>&lt;p&gt;Giving a star to an open source library means to a lot to the developers and consumers of the library. Because this will give the developers a positive impact to make the library better. It is definitely a way to tell gently to the developers, there are people out there who use that library.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvwuzps7nrctrztyqgylz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvwuzps7nrctrztyqgylz.png" alt="rails/rails repos current star count at 2018-07-15"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  As a consumer of the library
&lt;/h3&gt;

&lt;p&gt;If you are using an open source library, go ahead and find its Github/Gitlab (or any version control source) and give it a star. If you need to use a high-quality generic library, you should help to bring new people to the library. Starring will bring quality and aliveness to the library. One of the people that you bring, might be the next contributor to the library.&lt;/p&gt;

&lt;h3&gt;
  
  
  To support the work or idea
&lt;/h3&gt;

&lt;p&gt;You find an open source library in the following interests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Like the idea&lt;/li&gt;
&lt;li&gt;Plan to use it in your current or next project&lt;/li&gt;
&lt;li&gt;Like the software design of the library&lt;/li&gt;
&lt;li&gt;A topic of interests like distributed systems, data structures, useful links&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't forget that any positive starring activity will bring more people to like the library with the social impact. This positive impact will also bring more contributors to the library. And will prevent the library to get out-dated.&lt;/p&gt;

&lt;p&gt;These are only my ideas while starring a library, please do not hesitate to share yours. I will be happy to include in the story including your name.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>developers</category>
      <category>community</category>
      <category>discuss</category>
    </item>
  </channel>
</rss>
