How to use a singleton in go

agolangf · · 306 次点击    
这是一个分享于 的资源,其中的信息可能已经有所发展或是发生改变。
<p>Hey, I’ve built a go based rest api, this rest api uses client to get gather data.(the client takes in a user name password and fetches some data from a server). I have put the client code in a singleton block to make sure there is only one copy of the client at any given time. </p> <p>The issue I’m facing is that this created client outlives the request. So if I send in another request with a different username and password, the singleton stops the creation of a new client and uses the previously created client to fetch data. </p> <p>What is the right way to do this kind of thing in go ?? </p> <p>Thanks </p> <hr/>**评论:**<br/><br/>md2perpe: <pre><p>Why do you only want one copy of the client at any given time?</p> <p>Can you put some example code on the Go playground?</p></pre>earthboundkid: <pre><p>It sounds like what they really want is a semaphore to limit concurrency but it’s not being done the way it should. </p></pre>klauspost: <pre><blockquote> <p>another request with a different username and password</p> </blockquote> <p>If your client contains username and password, wouldn&#39;t it be correct to create a new client?</p> <p>Ie. a standard <code>func NewClient(o ...Option) (*Client, error)</code> function users can use to get a new client. If you need a &#34;singleton&#34;, the caller can store it in an exported package variable, if passing it is too much of a hazzle.</p></pre>titpetric: <pre><p>Singletons are an anti pattern. You&#39;re most likely looking at creating a session, and then using the session ID to hold the user details between browser pageloads. The difference between PHP (session_start(), etc.) is that a singleton there only lives on the one/single request, you will start with a blank pageload for every request. Go is a long running application server, meaning that the singletons you create would persist between pageloads. If you don&#39;t want them to persist - don&#39;t create them in the global namespace, but limit them in your HTTP handler. Of course, they will not be singletons anymore, which is sort of good :)</p></pre>e1ch1: <pre><p>Packages in go are singletons, that&#39;s not an anti-pattern, it&#39;s just design decisions made to achieve some specific result.</p></pre>titpetric: <pre><p>In the context, the OP seems to be using a global object (or package) for state management, which most definitely is an anti-pattern in singleton use.</p> <p>A good read which references a bad singleton on a similar example of user data: <a href="https://krakendev.io/blog/antipatterns-singletons" rel="nofollow">https://krakendev.io/blog/antipatterns-singletons</a> ; a simple rule of thumb would be, that if you need to manage per-request data, to create it in the request handler and pass it from there down to your internal APIs.</p></pre>shovelpost: <pre><p>Remove state (username and password) from the client and your problem will vanquish. You can pass them into a method instead:</p> <pre><code>func (c *Client) GatherData(username, password string) </code></pre></pre>carmark: <pre><p>How about <code>sync.Once</code>?</p></pre>

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

306 次点击  
加入收藏 微博
0 回复
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传