Sign in
Log inSign up
Sayed Alesawy

129 likes

·

24.9K reads

27 comments

Kevin Wan
Kevin Wan
May 28, 2021

Great article! I've been used c/c++/c#/java/python for many years, and using go since 2013. All the mentioned lessons I have met before. Thanks for sharing!

2
·
Kieran Roberts jkbasjkbfbjaksbfjbjasbfjbdsjkfb
Kieran Roberts jkbasjkbfbjaksbfjbjasbfjbdsjkfb

I really enjoyed reading your article Sayed Alesawy. Go is not a language I am familiar with but it seems really interesting. Thanks for sharing!

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 22, 2021

Thank you! Glad you liked it.

·
Chindukuri Pavan
Chindukuri Pavan
May 23, 2021

Now, Your article made me start learning GO. But I have no experience with strictly typed languages.

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 23, 2021

That's great! I recommend checking this tutorial: golangbot.com/learn-golang-series along with the go tour here: tour.golang.org/welcome/1 and anything else you need later, there is probably a godoc for it.

2
·
Shaswat Singh
Shaswat Singh
May 23, 2021

nice article by the way...

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 23, 2021

Thank you! Glad you liked it.

·
Yong Wei Lun
Yong Wei Lun
May 24, 2021

Great! Can't wait for part two

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 24, 2021

Thank you! Hopefully, I will get to it soon.

·
Phillip Ninan
Phillip Ninan
May 24, 2021

Very cool read! I have heard great things about Go. This is a cool overview of some of its functionality. It seems to handle concurrency very well!

Thank you!

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 24, 2021

Thank you! Yes, Go is really great for writing concurrent applications and it's also blazing fast and doesn't really take that much development time to build, so all in all, quite an awesome language.

·
Maxim Pak
Maxim Pak
May 28, 2021

As far as I know, in most cases singletons are considered an anti-pattern. It's probably better to explicitly pass *sql.DB object around

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·May 29, 2021

I am not really sure why do you think so. I mean my rationale is that you will probably need to do some initialization of some sort, like maybe pass connection configurations or something like that. You will probably do it in an init method or something, then after that you can use the connection variable. Looks like if somebody forgot to init, they will run into problems and here comes the usefulness of having a wrapper method. And if you have a wrapper method and it's not singleton, that will be problematic as well.

I am interested to know why do you think it's an anti pattern or if you have a resource that supports that. Thanks for the thought tho!

·
George
George
Jun 1, 2021

Singletons are horrible advice, don't follow that pattern. Anything that creates a static, package level variable is bad.

·
·4 replies
Andrey Panin
Andrey Panin
Jun 2, 2021

Care to elaborate on that?

·
George
George
1
·
Sayed Alesawy
Sayed Alesawy
Author
·Jun 2, 2021

I know there is a somewhat compelling argument against singleton in general. I am not sure how could I replace it tho and get the same effect? I will check the article you mentioned. Thanks for the comment!

·
George
George
Jun 2, 2021

Sayed Alesawy Replace it with a regular struct which accepts the dependency on it.

If it gets complex you can write a factory method on the struct.

1
·
Andrey Panin
Andrey Panin
Jun 2, 2021

The approach with channels from (1) looks dubious to me. You have omitted the important part explaining it by clarity, but what is missing is important for understanding of the concept. Maybe it's just me.

You have to call server.Run() in a goroutine in (4), otherwise your code will block at this method.

·
·1 reply
Sayed Alesawy
Sayed Alesawy
Author
·Jun 2, 2021

Yes, you are correct about 4, it was a typo, I corrected it. Thank you!

About 1, I dunno, might be up to taste but I have seen it in a lot of places and written by people who are go contributors actually. It's definitely less verbose but if you are very familiar with channels, it's as understandable in my opinion.

·
Oleksiy
Oleksiy
Jun 13, 2021

Is it just me or does sync.Once compound the problem? While &sql.Open(...) is running, all other DBConnection will return nil?

·
·4 replies
Sayed Alesawy
Sayed Alesawy
Author
·Jun 13, 2021

The idea here is that you only need to open a database connection once. According to go docs, the Open() function returns a connection that is "safe for concurrent use by multiple goroutines and maintains its own pool of idle connections. Thus, the Open function should be called just once. It is rarely necessary to close a DB."

So you can call on the init function on start (there will be no other calls to it at this point) and that's it. You can refer to the docs here: golang.org/pkg/database/sql/#Open

·
Oleksiy
Oleksiy
Jun 13, 2021

Sayed Alesawy As far as I understand, in this case sql.Open is just for example, which means there could be any other function with indefinite execution time.

I would like to return to the problem stated in paragraph 2 (without init function): ...Consider the case where 2 goroutines are calling the function DBConnection() at the same time. It's possible that the first goroutine reads the value of dbInstance and finds it nil and then proceeds to create a new connection...

Does dbOnce.Do block the rest of the function's calls for the execution time, or just let them pass by and return nil?

1
·
Sayed Alesawy
Sayed Alesawy
Author
·Jun 13, 2021

Oleksiy Oh, I understand what you mean now. That's a really nice case to think about.

As far as I know, calls to sync.Once won't return until the function f() inside the Do function returns. So if multiple goroutines call it concurrently, they will block waiting until the first call returns, then they will be executed, but of course they won't re-execute Once again.

I wrote this code: play.golang.org/p/ftvpEyhHDio to make sure and try it out. You can try changing the value of Sleep at line 22 to something bigger and you will see that the routines are blocked.

Considering this behavior, I still think it's good for initializations.

·
Oleksiy
Oleksiy
Jun 13, 2021

Sayed Alesawy Ah, great, then the question is off the table. Yes, I've now studied the Once.Do implementation, it's fun and seems to be specifically designed to lock other calls until the return from the function happens.

1
·
Mike Graf
Mike Graf
Sep 28, 2021

Thanks for sharing, we'll especially want people to ensure they understand CSP (tony Hoare) , and know about the go proverbs ( a source of the sharing memory quote: go-proverbs.github.io )

Good video on the topic: youtube.com/watch?v=oV9rvDllKEg

A lot of go problems seem to stem from not understanding how to model their program concurrently

·
Yosry Ahmed
Yosry Ahmed
Jul 10, 2022

Great Article! Very informative.

Just a quick note, you can’t actually intercept SIGKILL (or SIGSTOP for that matter), I believe you meant SIGTERM or SIGINT in your example in (4).

·