<?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>Forem: Hậu Xe</title>
    <description>The latest articles on Forem by Hậu Xe (@hauxe).</description>
    <link>https://forem.com/hauxe</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%2F92649%2Fa1c2f2f8-26cc-42b8-96ea-fa7d1093276d.jpeg</url>
      <title>Forem: Hậu Xe</title>
      <link>https://forem.com/hauxe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/hauxe"/>
    <language>en</language>
    <item>
      <title>Golang: Combining Signals by OR, AND</title>
      <dc:creator>Hậu Xe</dc:creator>
      <pubDate>Thu, 16 Aug 2018 04:26:07 +0000</pubDate>
      <link>https://forem.com/hauxe/golang-combining-signals-by-or-and-48dd</link>
      <guid>https://forem.com/hauxe/golang-combining-signals-by-or-and-48dd</guid>
      <description>&lt;p&gt;In Golang if we want to avoid goroutine leaks, usually we use a special &lt;em&gt;done&lt;/em&gt; channel to signal to a specific goroutine that it needs to be closed. And if we work with many modules which have it’s own done channels then we may want to combine those signals into one signal in form of OR or AND logic&lt;/p&gt;

&lt;h3&gt;
  
  
  The OR combining signals
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;If &lt;strong&gt;any&lt;/strong&gt; of the signals is received then emit the combined signal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The implementation below use a number of 2 is maximum channels to be combined, you can change to any number you want:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// OR function combines all signal from channels into a single channel with Or condition
func OR(channels ...&amp;lt;-chan interface{}) &amp;lt;-chan interface{} {
    switch len(channels) {
    case 0:
        return nil
    case 1:
        return channels[0]
    }
    orDone := make(chan interface{})
    go func() {
        defer close(orDone)
        switch len(channels) {
        case 2:
            select {
            case &amp;lt;-channels[0]:
            case &amp;lt;-channels[1]:
            }
        default:
            select {
            case &amp;lt;-channels[0]:
            case &amp;lt;-channels[1]:
            case &amp;lt;-channels[2]:
            case &amp;lt;-OR(append(channels[3:], orDone)...):
            }
        }
    }()
    return orDone
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first case of switch statement is check if length of channels is 0, we will block forever by returning a &lt;strong&gt;nil&lt;/strong&gt; channel, this is correct behavior when there no signal at all&lt;/p&gt;

&lt;p&gt;The second case of switch statement is if only one channel is passed into this function we will simply return it!&lt;/p&gt;

&lt;p&gt;Then we create a &lt;strong&gt;orChan&lt;/strong&gt; for combining all signals from channel, then fork a new goroutine for combine at most 2 channel into &lt;strong&gt;orChan&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Notice that when we recursively call &lt;strong&gt;OR&lt;/strong&gt; function, we pass &lt;strong&gt;orChan&lt;/strong&gt; again to this function because of logic OR, we need to respect the &lt;strong&gt;orChan&lt;/strong&gt; from previous combination&lt;/p&gt;

&lt;h3&gt;
  
  
  The AND combining signals
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;If &lt;strong&gt;all&lt;/strong&gt; of the signals is received then emit the combined signal&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The implementation use a very excited knowledge in Golang: in the select statement if right-hand side of a written channel is a receiving channel , the select statement will wait for all receiving channels to be complete before sending to the left-hand side channel&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// AND function combines all signal from channels into a single channel with And condition
func AND(channels ...&amp;lt;-chan interface{}) &amp;lt;-chan interface{} {
    switch len(channels) {
    case 0:
        return nil
    case 1:
        return channels[0]
    }
    andDone := make(chan interface{})
    collector := make(chan interface{}, len(channels))
    go func() {
        defer close(andDone)
        switch len(channels) {
        case 2:
            select {
            case collector &amp;lt;- &amp;lt;-channels[0]:
            case collector &amp;lt;- &amp;lt;-channels[1]:
            }
        default:
            select {
            case collector &amp;lt;- &amp;lt;-channels[0]:
            case collector &amp;lt;- &amp;lt;-channels[1]:
            case collector &amp;lt;- &amp;lt;-channels[2]:
            case collector &amp;lt;- &amp;lt;-AND(channels[3:]...):
            }
        }
    }()
    return andDone
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It’s very similar to the OR implementation version with 3 important different points:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We create a buffered &lt;strong&gt;collector&lt;/strong&gt; channel for collecting signals from combining channels&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We pass &lt;strong&gt;collector&lt;/strong&gt; channel as left-hand side in &lt;em&gt;select&lt;/em&gt; statement&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We recursively call &lt;strong&gt;AND&lt;/strong&gt; function without pass in &lt;strong&gt;andChan&lt;/strong&gt; into it’s parameter list, because we’re waiting for all signals, there no need to respect to this signal again&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I implemented those function into this &lt;a href="https://github.com/hauxe/GoM/blob/master/event/combine_signal.go"&gt;Repo&lt;/a&gt;, feel free to use it by yourself! Thanks&lt;/p&gt;

</description>
      <category>go</category>
      <category>channel</category>
      <category>signal</category>
    </item>
    <item>
      <title>Golang: HTTP Serve static files correctly</title>
      <dc:creator>Hậu Xe</dc:creator>
      <pubDate>Tue, 14 Aug 2018 09:25:55 +0000</pubDate>
      <link>https://forem.com/hauxe/golang-http-serve-static-files-correctly-2oj2</link>
      <guid>https://forem.com/hauxe/golang-http-serve-static-files-correctly-2oj2</guid>
      <description>&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%2F3n9poq268hj3xww3dc1s.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%2F3n9poq268hj3xww3dc1s.png" alt="Demo"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  The EasyWay
&lt;/h4&gt;

&lt;p&gt;Handle static files in Golang is very straightforward just one line of code to do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http.Handle("/", http.StripPrefix(strings.TrimRight(path, "/"), http.FileServer(http.Dir(directory))))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;where path is &lt;em&gt;http&lt;/em&gt; path and &lt;em&gt;directory&lt;/em&gt; is the static directory you want to serve over http&lt;/p&gt;

&lt;p&gt;But, there is a problem, by accessing to root url you can expose your directory structure to public as well =_=:&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%2Frhetq5z09jq57m7uovi7.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%2Frhetq5z09jq57m7uovi7.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;listing directory&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The code is:&lt;br&gt;
&lt;a href="https://gist.github.com/hauxe/09cd680deb9c8c4e36d61568db57647b" rel="noopener noreferrer"&gt;https://gist.github.com/hauxe/09cd680deb9c8c4e36d61568db57647b&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We need to do something to prevent this danger&lt;/p&gt;

&lt;p&gt;First Don’t use default HTTP File server, we’ll create our custome http file server and reject which request accessing to directory path:&lt;br&gt;
&lt;a href="https://gist.github.com/hauxe/f88a87f4037bca23f04f6d100f6e08d4#file-http_static_custom_http_server-go" rel="noopener noreferrer"&gt;https://gist.github.com/hauxe/f88a87f4037bca23f04f6d100f6e08d4#file-http_static_custom_http_server-go&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The custom rule that I chose is: if accessing to a directory, and if that directory contains index.html, return it, otherwise return error&lt;/p&gt;

&lt;p&gt;Second Register HTTP File server with this custom struct:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fileServer := http.FileServer(FileSystem{http.Dir(directory)})

http.Handle("/", http.StripPrefix(strings.TrimRight(path, "/"), fileServer))
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you access it again:&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%2Fio9t8jjcgcf9i79prwb5.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%2Fio9t8jjcgcf9i79prwb5.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Successfully prevents&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Put a &lt;strong&gt;index.html&lt;/strong&gt; file into statics folder and run example again with new code:&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%2F5p9y87gb6w47vvdomui3.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%2F5p9y87gb6w47vvdomui3.png"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;After put index.html&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Full working code:&lt;br&gt;
&lt;a href="https://gist.github.com/hauxe/f2ea1901216177ccf9550a1b8bd59178#file-http_static_correct-go" rel="noopener noreferrer"&gt;https://gist.github.com/hauxe/f2ea1901216177ccf9550a1b8bd59178#file-http_static_correct-go&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;I have made a &lt;a href="https://github.com/hauxe/GoM/blob/master/http/filesystem_handler.go" rel="noopener noreferrer"&gt;Repo&lt;/a&gt; for this purpose which return the http handler for it&lt;/p&gt;

</description>
      <category>go</category>
      <category>http</category>
      <category>staticfile</category>
    </item>
  </channel>
</rss>
