<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Queue on WebDevStation</title>
    <link>https://webdevstation.com/tags/queue/</link>
    <description>1 article tagged Queue — tutorials, code examples and notes from building real systems, newest first.</description>
    <generator>Hugo</generator>
    <language>en</language>
    <managingEditor>Alex</managingEditor>
    <webMaster>Alex</webMaster>
    <copyright>© 2026 WebDevStation</copyright>
    <lastBuildDate>Tue, 12 Jan 2021 18:40:24 +0000</lastBuildDate>
    <atom:link href="https://webdevstation.com/tags/queue/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>A Simple Queue Implementation in Golang with channels</title>
      <link>https://webdevstation.com/posts/simple-queue-implementation-in-golang/</link>
      <pubDate>Tue, 12 Jan 2021 18:40:24 +0000</pubDate>
      <author>Alex</author>
      <guid isPermaLink="true">https://webdevstation.com/posts/simple-queue-implementation-in-golang/</guid>
      <description>Learn how to implement a simple, efficient queue in Go using channels and goroutines. This practical guide shows you how to process operations sequentially with Go&#39;s…</description>
      <content:encoded><![CDATA[<p>In this post, I&rsquo;m going to show the way how we can implement a simple queue in Golang, using channels.</p>
<p>Let&rsquo;s clarify why would we ever use a queue? There many possible reasons. The most common one it&rsquo;s when
we have a list of operations (actions) and we need to process them one by one. This list either could be
static or dynamic (when new items arriving continuously).
As in the real-life, queue needed to be processed by something or someone. Imagine, a line of people in the
supermarket nearby cashier.
<div style="width:100%;height:0;padding-bottom:40%;position:relative;">
    <iframe src="https://giphy.com/embed/3o752ai3lDpXOw3yDu"
      width="100%" height="100%" style="position:absolute"
      frameBorder="0" allowFullScreen></iframe></div></p>
<p>Every customer in this line holds his own specific products and wants to
pay for them. In other words, every queue item has it own set of data with instructions. A cashier serves
his clients from a line one by one (processes queue items).
What would happen if all customers decided to pay simultaneously? Probably, something like this:
<div style="width:100%;height:0;padding-bottom:40%;position:relative;">
    <iframe src="https://giphy.com/embed/ls4p6mWzR0G9dRpwqm"
      width="100%" height="100%" style="position:absolute"
      frameBorder="0" allowFullScreen></iframe></div></p>
<p>To prevent this situation, let&rsquo;s implement a queue in Go quickly :)
First, we need to create a Queue struct and constructor function:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span>  <span style="color:#75715e">// Queue holds name, list of jobs and context with cancel.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Queue</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>     <span style="color:#a6e22e">name</span>   <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>     <span style="color:#a6e22e">jobs</span>   <span style="color:#66d9ef">chan</span> <span style="color:#a6e22e">Job</span>
</span></span><span style="display:flex;"><span>     <span style="color:#a6e22e">ctx</span>    <span style="color:#a6e22e">context</span>.<span style="color:#a6e22e">Context</span>
</span></span><span style="display:flex;"><span>     <span style="color:#a6e22e">cancel</span> <span style="color:#a6e22e">context</span>.<span style="color:#a6e22e">CancelFunc</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// Job - holds logic to perform some operations during queue execution.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Job</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Name</span>   <span style="color:#66d9ef">string</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Action</span> <span style="color:#66d9ef">func</span>() <span style="color:#66d9ef">error</span> <span style="color:#75715e">// A function that should be executed when the job is running.</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">// NewQueue instantiates new queue.</span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">func</span> <span style="color:#a6e22e">NewQueue</span>(<span style="color:#a6e22e">name</span> <span style="color:#66d9ef">string</span>) <span style="color:#f92672">*</span><span style="color:#a6e22e">Queue</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">ctx</span>, <span style="color:#a6e22e">cancel</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">context</span>.<span style="color:#a6e22e">WithCancel</span>(<span style="color:#a6e22e">context</span>.<span style="color:#a6e22e">Background</span>())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Queue</span>{
</span></span><span style="display:flex;"><span>       <span style="color:#a6e22e">jobs</span>:   make(<span style="color:#66d9ef">chan</span> <span style="color:#a6e22e">Job</span>),
</span></span><span style="display:flex;"><span>       <span style="color:#a6e22e">name</span>:   <span style="color:#a6e22e">name</span>,
</span></span><span style="display:flex;"><span>       <span style="color:#a6e22e">ctx</span>:    <span style="color:#a6e22e">ctx</span>,
</span></span><span style="display:flex;"><span>       <span style="color:#a6e22e">cancel</span>: <span style="color:#a6e22e">cancel</span>,
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span></code></pre></div><p>As you have seen above, I&rsquo;ve declared an unbuffered channel (with no capacity) to hold Jobs in a Queue.
Channels will give us a really powerful possibility to work in a concurrent environment.
Moreover, our queue has a context with cancellation. This will help us to understand when all jobs in the queue were
finished in all goroutines and after that, we can free all resources.</p>
<p>In the code below we are going to add some methods to the <code>queue</code> struct.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// AddJobs adds jobs to the queue and cancels channel.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">q</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Queue</span>) <span style="color:#a6e22e">AddJobs</span>(<span style="color:#a6e22e">jobs</span> []<span style="color:#a6e22e">Job</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">var</span> <span style="color:#a6e22e">wg</span> <span style="color:#a6e22e">sync</span>.<span style="color:#a6e22e">WaitGroup</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">wg</span>.<span style="color:#a6e22e">Add</span>(len(<span style="color:#a6e22e">jobs</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">job</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">jobs</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Goroutine which adds job to the queue.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">go</span> <span style="color:#66d9ef">func</span>(<span style="color:#a6e22e">job</span> <span style="color:#a6e22e">Job</span>) {
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">q</span>.<span style="color:#a6e22e">AddJob</span>(<span style="color:#a6e22e">job</span>)
</span></span><span style="display:flex;"><span>      <span style="color:#a6e22e">wg</span>.<span style="color:#a6e22e">Done</span>()
</span></span><span style="display:flex;"><span>    }(<span style="color:#a6e22e">job</span>)
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">go</span> <span style="color:#66d9ef">func</span>() {
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">wg</span>.<span style="color:#a6e22e">Wait</span>()
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Cancel queue channel, when all goroutines were done.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">q</span>.<span style="color:#a6e22e">cancel</span>()
</span></span><span style="display:flex;"><span>  }()
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// AddJob sends job to the channel.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">q</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Queue</span>) <span style="color:#a6e22e">AddJob</span>(<span style="color:#a6e22e">job</span> <span style="color:#a6e22e">Job</span>) {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">q</span>.<span style="color:#a6e22e">jobs</span> <span style="color:#f92672">&lt;-</span> <span style="color:#a6e22e">job</span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;New job %s added to %s queue&#34;</span>, <span style="color:#a6e22e">job</span>.<span style="color:#a6e22e">Name</span>, <span style="color:#a6e22e">q</span>.<span style="color:#a6e22e">name</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Next, let&rsquo;s add a <code>Run()</code> method to the <code>Job</code> struct, which should execute a job&rsquo;s action (the main purpose of the job).</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// Run performs job execution.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">j</span> <span style="color:#a6e22e">Job</span>) <span style="color:#a6e22e">Run</span>() <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Job running: %s&#34;</span>, <span style="color:#a6e22e">j</span>.<span style="color:#a6e22e">GetName</span>())
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">j</span>.<span style="color:#a6e22e">Action</span>()
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">return</span> <span style="color:#a6e22e">err</span>
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Alright, now let&rsquo;s create a worker, who will be responsible for serving our queue.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">// Worker responsible for queue serving.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">type</span> <span style="color:#a6e22e">Worker</span> <span style="color:#66d9ef">struct</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#a6e22e">Queue</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Queue</span>
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// NewWorker initializes a new Worker.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">NewWorker</span>(<span style="color:#a6e22e">queue</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Queue</span>) <span style="color:#f92672">*</span><span style="color:#a6e22e">Worker</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">return</span> <span style="color:#f92672">&amp;</span><span style="color:#a6e22e">Worker</span>{
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">Queue</span>: <span style="color:#a6e22e">queue</span>,
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// DoWork processes jobs from the queue (jobs channel).</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> (<span style="color:#a6e22e">w</span> <span style="color:#f92672">*</span><span style="color:#a6e22e">Worker</span>) <span style="color:#a6e22e">DoWork</span>() <span style="color:#66d9ef">bool</span> {
</span></span><span style="display:flex;"><span>  <span style="color:#66d9ef">for</span> {
</span></span><span style="display:flex;"><span>    <span style="color:#66d9ef">select</span> {
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">// if context was canceled.</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">case</span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">w</span>.<span style="color:#a6e22e">Queue</span>.<span style="color:#a6e22e">ctx</span>.<span style="color:#a6e22e">Done</span>():
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Printf</span>(<span style="color:#e6db74">&#34;Work done in queue %s: %s!&#34;</span>, <span style="color:#a6e22e">w</span>.<span style="color:#a6e22e">Queue</span>.<span style="color:#a6e22e">name</span>, <span style="color:#a6e22e">w</span>.<span style="color:#a6e22e">Queue</span>.<span style="color:#a6e22e">ctx</span>.<span style="color:#a6e22e">Err</span>())
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">return</span> <span style="color:#66d9ef">true</span>
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">// if job received.</span>
</span></span><span style="display:flex;"><span>      <span style="color:#66d9ef">case</span> <span style="color:#a6e22e">job</span> <span style="color:#f92672">:=</span> <span style="color:#f92672">&lt;-</span><span style="color:#a6e22e">w</span>.<span style="color:#a6e22e">Queue</span>.<span style="color:#a6e22e">jobs</span>:
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">err</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">job</span>.<span style="color:#a6e22e">Run</span>()
</span></span><span style="display:flex;"><span>        <span style="color:#66d9ef">if</span> <span style="color:#a6e22e">err</span> <span style="color:#f92672">!=</span> <span style="color:#66d9ef">nil</span> {
</span></span><span style="display:flex;"><span>          <span style="color:#a6e22e">log</span>.<span style="color:#a6e22e">Print</span>(<span style="color:#a6e22e">err</span>)
</span></span><span style="display:flex;"><span>          <span style="color:#66d9ef">continue</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>    }
</span></span><span style="display:flex;"><span>  }
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>Pay attention to the <code>DoWork()</code> method. There we have a for loop, which is listening for the jobs channel,
and if the channel receives a job, it executes it, by running <code>job.Run()</code>. If the context was canceled, it means,
that all jobs were executed and we can exit from the loop.</p>
<p>Now, let&rsquo;s see how we can work with just created queue functionality on a real example.
I&rsquo;m going to create a simple program, where we need to import new products into our storage.</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#f92672">package</span> <span style="color:#a6e22e">main</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#f92672">import</span> (
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;fmt&#34;</span>
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;github.com/alexsergivan/blog-examples/queue/queue&#34;</span>
</span></span><span style="display:flex;"><span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">// Our products storage.</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">products</span> = []<span style="color:#66d9ef">string</span>{
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;books&#34;</span>,
</span></span><span style="display:flex;"><span>	<span style="color:#e6db74">&#34;computers&#34;</span>,
</span></span><span style="display:flex;"><span>}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">func</span> <span style="color:#a6e22e">main</span>()  {
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// New products, which we need to add to our products storage.</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">newProducts</span> <span style="color:#f92672">:=</span> []<span style="color:#66d9ef">string</span>{
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;apples&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;oranges&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;wine&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;bread&#34;</span>,
</span></span><span style="display:flex;"><span>		<span style="color:#e6db74">&#34;orange juice&#34;</span>,
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// New queue initialization.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">productsQueue</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">queue</span>.<span style="color:#a6e22e">NewQueue</span>(<span style="color:#e6db74">&#34;NewProducts&#34;</span>)
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">var</span> <span style="color:#a6e22e">jobs</span> []<span style="color:#a6e22e">queue</span>.<span style="color:#a6e22e">Job</span>
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Range over new products.</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">for</span> <span style="color:#a6e22e">_</span>, <span style="color:#a6e22e">newProduct</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">range</span> <span style="color:#a6e22e">newProducts</span> {
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// We need to do this, because variables declared in for loops are passed by reference.</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Otherwise, our closure will always receive the last item from the newProducts.</span>
</span></span><span style="display:flex;"><span>        <span style="color:#a6e22e">product</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">newProduct</span>
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Defining of the closure, where we add a new product to our simple storage (products slice)</span>
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">action</span> <span style="color:#f92672">:=</span> <span style="color:#66d9ef">func</span>() <span style="color:#66d9ef">error</span> {
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">products</span> = append(<span style="color:#a6e22e">products</span>, <span style="color:#a6e22e">product</span>)
</span></span><span style="display:flex;"><span>			<span style="color:#66d9ef">return</span> <span style="color:#66d9ef">nil</span>
</span></span><span style="display:flex;"><span>        }
</span></span><span style="display:flex;"><span>        <span style="color:#75715e">// Append job to jobs slice.</span>
</span></span><span style="display:flex;"><span>		<span style="color:#a6e22e">jobs</span> = append(<span style="color:#a6e22e">jobs</span>, <span style="color:#a6e22e">queue</span>.<span style="color:#a6e22e">Job</span>{
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">Name</span>:   <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Sprintf</span>(<span style="color:#e6db74">&#34;Importing new product: %s&#34;</span>, <span style="color:#a6e22e">newProduct</span>),
</span></span><span style="display:flex;"><span>			<span style="color:#a6e22e">Action</span>: <span style="color:#a6e22e">action</span>,
</span></span><span style="display:flex;"><span>		})
</span></span><span style="display:flex;"><span>	}
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Adds jobs to the queue.</span>
</span></span><span style="display:flex;"><span>	<span style="color:#a6e22e">productsQueue</span>.<span style="color:#a6e22e">AddJobs</span>(<span style="color:#a6e22e">jobs</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Defines a queue worker, which will execute our queue.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">worker</span> <span style="color:#f92672">:=</span> <span style="color:#a6e22e">queue</span>.<span style="color:#a6e22e">NewWorker</span>(<span style="color:#a6e22e">productsQueue</span>)
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Execute jobs in queue.</span>
</span></span><span style="display:flex;"><span>    <span style="color:#a6e22e">worker</span>.<span style="color:#a6e22e">DoWork</span>()
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">// Prints products storage after queue execution.</span>
</span></span><span style="display:flex;"><span>	<span style="color:#66d9ef">defer</span> <span style="color:#a6e22e">fmt</span>.<span style="color:#a6e22e">Print</span>(<span style="color:#a6e22e">products</span>)
</span></span><span style="display:flex;"><span>}
</span></span></code></pre></div><p>After executing this program, it will print out this data:</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>2021/01/12 22:10:33 New job Importing new product: apples added to NewProducts queue
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Job running: Importing new product: apples
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Job running: Importing new product: wine
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Job running: Importing new product: oranges
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Job running: Importing new product: bread
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Job running: Importing new product: orange juice
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 New job Importing new product: orange juice added to NewProducts queue
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 New job Importing new product: oranges added to NewProducts queue
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 New job Importing new product: bread added to NewProducts queue
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 New job Importing new product: wine added to NewProducts queue
</span></span><span style="display:flex;"><span>2021/01/12 22:10:33 Work <span style="color:#66d9ef">done</span> in queue NewProducts: context canceled!
</span></span><span style="display:flex;"><span><span style="color:#f92672">[</span>books computers apples wine oranges bread orange juice<span style="color:#f92672">]</span>%
</span></span></code></pre></div><p>Please notice the last line in the logs:
<code>[books computers apples wine oranges bread orange juice]</code>
As you can see, the order is different from the order in <code>newProducts</code> slice. It happens because of goroutines nature.
Sometimes one goroutine needs more time to finish its work than another. For the scenario, when the order is important,
I will write a separate post later.</p>
<p>For now, that&rsquo;s it :) Hope it was helpful!</p>
<p>The source code you can find <a href="https://github.com/alexsergivan/blog-examples/tree/master/queue">here</a></p>
<p>A queue like this processes work in order, one item at a time. When order does not matter and you want several items in flight instead, reach for <a href="/posts/worker-pools-in-go-with-errgroup/">worker pools in Go with errgroup</a>. Either way, make sure the consumer stops cleanly on shutdown — see <a href="/posts/graceful-shutdown-in-go-web-services/">graceful shutdown in Go web services</a>.</p>]]></content:encoded>
      <category>Go Programming</category>
      <category>Backend Development</category>
    </item>
  </channel>
</rss>
