Re: [go-nuts] Sharing data via Mutex vs. Channel
Thanks that sounds reasonable to me -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Sharing data via Mutex vs. Channel
Hi folks, somwhere on my golang journey ("don't k now where and when") I was teached that mutexes are very expensive and we should prefer to communicate over channels instead of working with mutexes. I trusted it until today. I explained it to our aprentice based on my knowledge and he asked me if i can show him the performance difference. Therefore I wrote this little demo with the expectation that the channel solution will beat the mutex one and was really surprised when I saw that the mutex based solution beats the channels one most of the time by factor 2. https://play.golang.org/p/Kf9VBSoTLcU What am I missing here or is it not true anymore that mutexes are so expensive that we should prefer Communicating over Sharing. kind regards Reinhard Lüdiger -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Tour Of go Page 8 in Basics does not work.
Hey List, is this the right place to get the tour of go fixed? The example on the following page https://tour.golang.org/basics/8 terminates unexpected with error process took to long. kind regards Reinhard Lüdiger -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] os.WriteFile not writing files in long running process
Maybe you are running out of sockets due to the missing close on the response body after read -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Is it possible to unmarshall Json by selecting the struct from a field in the Json?
Maybe https://github.com/mitchellh/mapstructure Will help you a bit -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Re: Long running task in select case
Yea looks a bit easier Kind regards Reinhard -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Re: Long running task in select case
Not Tested sofar by myself but https://github.com/dc0d/goroutines seems to hide all the complexity in a nice streamlined API. Am Montag, 19. März 2018 08:46:07 UTC+1 schrieb Sathish VJ: > > Looks like this last one works but also quite complicated. > > One question ... what is the effect of having "default" on line 24 as > empty? > > > On 18 March 2018 at 14:21, 'Reinhard Luediger' via golang-nuts < > golan...@googlegroups.com > wrote: > >> I came to the following solution for my long running tasks, using >> go-routines & the context package, >> >> https://play.golang.org/p/2V_29lHt4Wn >> >> package main >> >> import ( >>"context" >>"fmt" >>"time" >> ) >> >> //LongRunningTask >> func LongRunningTask(ctx context.Context, index int) (err error) { >>// we'll signal on that channel when we finished >>var finished chan struct{} >>fmt.Printf("Starting task %d at: %s\n", index, time.Now()) >>var cancelWork = make(chan struct{},0) >>go func() { >> workloop: >> for i:= 0 ;i < 10 ;i++{ >> // sleeping for a long time >> time.Sleep(time.Second * 2) >> select { >> case <-cancelWork: >> fmt.Printf("Canceling work for Index: %d\n",index) >> break workloop >> default: >> } >> } >> finished <- struct{}{} >>}() >> >>select { >>// when the task finished normal we'll get a notification on the finished >> channel >>case <-finished: >> fmt.Printf("Task %d finished at:%s\n", index, time.Now()) >> return nil >> >>// If the context gets canceled we receive a signal on that channel >>case <-ctx.Done(): >> err := ctx.Err() >> _=err >> //the context.Err() method gives us the reason why it was canceled >> fmt.Printf("task %d aborted reason:%s at: %s\n", index, ctx.Err(), >> time.Now()) >> cancelWork <- struct{}{} >> return ctx.Err() >>} >> >> } >> >> func main() { >>var ctx context.Context >> >>// get a new Context and the corresponding cancel function >>ctx, cancel := context.WithCancel(context.Background()) >> >>// create a new context with a timeout value of 4 Seconds derived from >> the context above >>ctx, _ = context.WithTimeout(ctx, time.Second*4) >> >>// Sleeping for one Second to clarify that the timeout is running from >> the point where it is created >>time.Sleep(time.Second * 1) >> >>fmt.Printf("Starting background tasks time %s", time.Now()) >>for i := 0; i < 7; i++ { >> go LongRunningTask(ctx, i) >> >>} >> >>// if we sllep longer than the timeout we'll see that the tasks will be >> canceled after timeout >>time.Sleep(time.Second * 8) >> >>// The call of the cancel function has only effect when we slept shorter >> then the defined timeout >>// if so the single call of the cancel function will send a cancellation >> information to all child context >>cancel() >> >>// Sleep a while to see the cancellation messages >>time.Sleep(time.Second * 4) >> >> } >> >> >> Am Freitag, 16. März 2018 15:45:00 UTC+1 schrieb Sathish VJ: >>> >>> All the examples I've seen use some kind of ticker to run various cases >>> of a select statement. But how does one run a long running task that is >>> still cancelable? >>> >>> >>> In the example below the quit part is never reached. >>> >>> https://play.golang.org/p/PLGwrUvKaqn (it does not run properly on >>> play.golang.org). >>> >>> package main >>> >>> >>> import ( >>> "fmt" >>> "os" >>> "time" >>> ) >>> >>> >>> func f(quit chan bool) { >>> for { >>>select { >>>case <-time.After(0 * time.Second): >>> // start long running task immediately. >>> for { >>>time.Sleep(500 * time.Millisecond) >>>fmt.Printf(". ") >>> } >>>case <-quit: >>> fmt.Println("quit called") >>> //deallocate resources in other long running task and then return >>> from function. >>> os.Exit(0) // or return >>>} >>> } >>> } >>> >>> >>> func main() { >>> var quit chan bool >>> go f(quit) >>> >>> >>> println("quit sending ... ") >>> quit <- true >>> println("after quit sent") >>> >>> >>> var i chan int >>> <-i >>> } >>> >>> >>> -- >> You received this message because you are subscribed to a topic in the >> Google Groups "golang-nuts" group. >> To unsubscribe from this topic, visit >> https://groups.google.com/d/topic/golang-nuts/l2A0PS91T0A/unsubscribe. >> To unsubscribe from this group and all its topics, send an email to >> golang-nuts...@googlegroups.com . >> For more options, visit https://groups.google.com/d/optout. >> > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Re: Long running task in select case
Well, without the NOP (empty) default case the loop of the working routine gets blocked by reading from the cancelation channel. So whenever you want to get a non blocking channel operation wether read or write remember the select with an empty default ;) kind regards Reinhard Am Montag, 19. März 2018 08:46:07 UTC+1 schrieb Sathish VJ: > > Looks like this last one works but also quite complicated. > > One question ... what is the effect of having "default" on line 24 as > empty? > > > On 18 March 2018 at 14:21, 'Reinhard Luediger' via golang-nuts < > golan...@googlegroups.com > wrote: > >> I came to the following solution for my long running tasks, using >> go-routines & the context package, >> >> https://play.golang.org/p/2V_29lHt4Wn >> >> package main >> >> import ( >>"context" >>"fmt" >>"time" >> ) >> >> //LongRunningTask >> func LongRunningTask(ctx context.Context, index int) (err error) { >>// we'll signal on that channel when we finished >>var finished chan struct{} >>fmt.Printf("Starting task %d at: %s\n", index, time.Now()) >>var cancelWork = make(chan struct{},0) >>go func() { >> workloop: >> for i:= 0 ;i < 10 ;i++{ >> // sleeping for a long time >> time.Sleep(time.Second * 2) >> select { >> case <-cancelWork: >> fmt.Printf("Canceling work for Index: %d\n",index) >> break workloop >> default: >> } >> } >> finished <- struct{}{} >>}() >> >>select { >>// when the task finished normal we'll get a notification on the finished >> channel >>case <-finished: >> fmt.Printf("Task %d finished at:%s\n", index, time.Now()) >> return nil >> >>// If the context gets canceled we receive a signal on that channel >>case <-ctx.Done(): >> err := ctx.Err() >> _=err >> //the context.Err() method gives us the reason why it was canceled >> fmt.Printf("task %d aborted reason:%s at: %s\n", index, ctx.Err(), >> time.Now()) >> cancelWork <- struct{}{} >> return ctx.Err() >>} >> >> } >> >> func main() { >>var ctx context.Context >> >>// get a new Context and the corresponding cancel function >>ctx, cancel := context.WithCancel(context.Background()) >> >>// create a new context with a timeout value of 4 Seconds derived from >> the context above >>ctx, _ = context.WithTimeout(ctx, time.Second*4) >> >>// Sleeping for one Second to clarify that the timeout is running from >> the point where it is created >>time.Sleep(time.Second * 1) >> >>fmt.Printf("Starting background tasks time %s", time.Now()) >>for i := 0; i < 7; i++ { >> go LongRunningTask(ctx, i) >> >>} >> >>// if we sllep longer than the timeout we'll see that the tasks will be >> canceled after timeout >>time.Sleep(time.Second * 8) >> >>// The call of the cancel function has only effect when we slept shorter >> then the defined timeout >>// if so the single call of the cancel function will send a cancellation >> information to all child context >>cancel() >> >>// Sleep a while to see the cancellation messages >>time.Sleep(time.Second * 4) >> >> } >> >> >> Am Freitag, 16. März 2018 15:45:00 UTC+1 schrieb Sathish VJ: >>> >>> All the examples I've seen use some kind of ticker to run various cases >>> of a select statement. But how does one run a long running task that is >>> still cancelable? >>> >>> >>> In the example below the quit part is never reached. >>> >>> https://play.golang.org/p/PLGwrUvKaqn (it does not run properly on >>> play.golang.org). >>> >>> package main >>> >>> >>> import ( >>> "fmt" >>> "os" >>> "time" >>> ) >>> >>> >>> func f(quit chan bool) { >>> for { >>>select { >>>case <-time.After(0 * time.Second): >>> // start long running task immediately. >>> for { >>>time.Sleep(500 * time.Millisecond) >>>fmt.Printf(". ") >
Re: [go-nuts] Re: Long running task in select case
Because then you have to deal with all the chennels by yourself. Using the Context API looks for me a bit cleaner and even easier. Am Montag, 19. März 2018 15:04:17 UTC+1 schrieb matthe...@gmail.com: > > Only a detail, but why not this instead as the API? > > func LongRunningTask(cancel <-chan struct{}, index int) (err error) { > > Matt > > On Monday, March 19, 2018 at 7:43:19 AM UTC-5, rog wrote: >> >> Why not something more like this? https://play.golang.org/p/3t4UtoFkoIt >> >> A lot of this comes down to what that long running task is doing. >> If it's hard at work doing computational work, the polling approach >> might be appropriate. >> If it's mostly waiting on external events then passing the context >> instance down and selecting >> on the Done channel is probably the way forward. >> >> On 19 March 2018 at 07:44, Sathish VJ <sath...@gmail.com> wrote: >> > Looks like this last one works but also quite complicated. >> > >> > One question ... what is the effect of having "default" on line 24 as >> empty? >> > >> > >> > On 18 March 2018 at 14:21, 'Reinhard Luediger' via golang-nuts >> > <golan...@googlegroups.com> wrote: >> >> >> >> I came to the following solution for my long running tasks, using >> >> go-routines & the context package, >> >> >> >> https://play.golang.org/p/2V_29lHt4Wn >> >> >> >> package main >> >> >> >> import ( >> >>"context" >> >>"fmt" >> >>"time" >> >> ) >> >> >> >> //LongRunningTask >> >> func LongRunningTask(ctx context.Context, index int) (err error) { >> >>// we'll signal on that channel when we finished >> >>var finished chan struct{} >> >>fmt.Printf("Starting task %d at: %s\n", index, time.Now()) >> >>var cancelWork = make(chan struct{},0) >> >>go func() { >> >> workloop: >> >> for i:= 0 ;i < 10 ;i++{ >> >> // sleeping for a long time >> >> time.Sleep(time.Second * 2) >> >> select { >> >> case <-cancelWork: >> >> fmt.Printf("Canceling work for Index: %d\n",index) >> >> break workloop >> >> default: >> >> } >> >> } >> >> finished <- struct{}{} >> >>}() >> >> >> >>select { >> >>// when the task finished normal we'll get a notification on the >> >> finished channel >> >>case <-finished: >> >> fmt.Printf("Task %d finished at:%s\n", index, time.Now()) >> >> return nil >> >> >> >>// If the context gets canceled we receive a signal on that channel >> >>case <-ctx.Done(): >> >> err := ctx.Err() >> >> _=err >> >> //the context.Err() method gives us the reason why it was >> canceled >> >> fmt.Printf("task %d aborted reason:%s at: %s\n", index, >> ctx.Err(), >> >> time.Now()) >> >> cancelWork <- struct{}{} >> >> return ctx.Err() >> >>} >> >> >> >> } >> >> >> >> func main() { >> >>var ctx context.Context >> >> >> >>// get a new Context and the corresponding cancel function >> >>ctx, cancel := context.WithCancel(context.Background()) >> >> >> >>// create a new context with a timeout value of 4 Seconds derived >> from >> >> the context above >> >>ctx, _ = context.WithTimeout(ctx, time.Second*4) >> >> >> >>// Sleeping for one Second to clarify that the timeout is running >> from >> >> the point where it is created >> >>time.Sleep(time.Second * 1) >> >> >> >>fmt.Printf("Starting background tasks time %s", time.Now()) >> >>for i := 0; i < 7; i++ { >> >> go LongRunningTask(ctx, i) >> >> >> >>} >> >> >> >>// if we sllep longer than the timeout we'll see that the tasks >> will be >> >> canceled after timeout
[go-nuts] Re: Long running task in select case
I came to the following solution for my long running tasks, using go-routines & the context package, https://play.golang.org/p/2V_29lHt4Wn package main import ( "context" "fmt" "time" ) //LongRunningTask func LongRunningTask(ctx context.Context, index int) (err error) { // we'll signal on that channel when we finished var finished chan struct{} fmt.Printf("Starting task %d at: %s\n", index, time.Now()) var cancelWork = make(chan struct{},0) go func() { workloop: for i:= 0 ;i < 10 ;i++{ // sleeping for a long time time.Sleep(time.Second * 2) select { case <-cancelWork: fmt.Printf("Canceling work for Index: %d\n",index) break workloop default: } } finished <- struct{}{} }() select { // when the task finished normal we'll get a notification on the finished channel case <-finished: fmt.Printf("Task %d finished at:%s\n", index, time.Now()) return nil // If the context gets canceled we receive a signal on that channel case <-ctx.Done(): err := ctx.Err() _=err //the context.Err() method gives us the reason why it was canceled fmt.Printf("task %d aborted reason:%s at: %s\n", index, ctx.Err(), time.Now()) cancelWork <- struct{}{} return ctx.Err() } } func main() { var ctx context.Context // get a new Context and the corresponding cancel function ctx, cancel := context.WithCancel(context.Background()) // create a new context with a timeout value of 4 Seconds derived from the context above ctx, _ = context.WithTimeout(ctx, time.Second*4) // Sleeping for one Second to clarify that the timeout is running from the point where it is created time.Sleep(time.Second * 1) fmt.Printf("Starting background tasks time %s", time.Now()) for i := 0; i < 7; i++ { go LongRunningTask(ctx, i) } // if we sllep longer than the timeout we'll see that the tasks will be canceled after timeout time.Sleep(time.Second * 8) // The call of the cancel function has only effect when we slept shorter then the defined timeout // if so the single call of the cancel function will send a cancellation information to all child context cancel() // Sleep a while to see the cancellation messages time.Sleep(time.Second * 4) } Am Freitag, 16. März 2018 15:45:00 UTC+1 schrieb Sathish VJ: > > All the examples I've seen use some kind of ticker to run various cases of > a select statement. But how does one run a long running task that is still > cancelable? > > > In the example below the quit part is never reached. > > https://play.golang.org/p/PLGwrUvKaqn (it does not run properly on > play.golang.org). > > package main > > > import ( > "fmt" > "os" > "time" > ) > > > func f(quit chan bool) { > for { >select { >case <-time.After(0 * time.Second): > // start long running task immediately. > for { >time.Sleep(500 * time.Millisecond) >fmt.Printf(". ") > } >case <-quit: > fmt.Println("quit called") > //deallocate resources in other long running task and then return > from function. > os.Exit(0) // or return >} > } > } > > > func main() { > var quit chan bool > go f(quit) > > > println("quit sending ... ") > quit <- true > println("after quit sent") > > > var i chan int > <-i > } > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Why should i use interface composistion
Unfortunately I have no tests yet. My plan is to use testify an mockery to generate tests for the Storage interface. I am aware of the fact that this only tests the app code . For testing the database methods we'll start integration tests against a real database., kind regards Reinhard Am Dienstag, 13. März 2018 19:53:02 UTC+1 schrieb matthe...@gmail.com: > > Writing to be testable is good but ideally tests shouldn’t drive the app > code. I’ll admit that I’ve written inconsistent database method patterns to > enable testing but then never wrote tests. > > In that case there’s a global DB type (type DB struct { *sql.DB }) with a > global var of the type initialized at the start of main. The HTTP handlers > call DB methods on the global var, then ideally all of those DB methods use > the receiver instead of the global var. I’m not sure how I’d start now, but > the idea is those methods could be tested with a different DB (I’m not > familiar with any sql in-memory ones). > > Can you describe your code and testing in more detail? > > Thanks, > Matt > > On Tuesday, March 13, 2018 at 12:39:40 PM UTC-5, Reinhard Luediger wrote: >> >> hi, >> >> first of all thanks for your reply. Indeed, the interface arose from the >> necessity of testing. Have you expierience with a memory sql driver? Could >> you recommend one? >> > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Why should i use interface composistion
@all thx for your comments I think i understand now how to deal with the advise of small interfaces. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Why should i use interface composistion
hi, first of all thanks for your reply. Indeed, the interface arose from the necessity of testing. Have you expierience with a memory sql driver? Could you recommend one? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
Re: [go-nuts] Why should i use interface composistion
hi, firstnat all thanks for your reply. Indeed, the interface arose from the necessity of testing. Have you expierience with a memory sql driver? Could you recommend one? -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] Why should i use interface composistion
Dear all, as far as I know it is recommended to keep actual interfaces as small as possible and to form bigger interfaces via interface composiston. Would be great if the community could advise me what the real benefits are. Lets say i want to create an interface for the database backend like the following example. //CleanupTimestamps is the interface which holds all methods related to cleanupTimestamps type CleanupTimestamps interface { SaveCleanupTimeStamp(taskName string, timestamp time.Time) (err error) GetCleanupTimeStamp(taskName string) (timestamp *time.Time, err error) } //ClusterFlavors interface holds all methods related to clusterFlavor type ClusterFlavors interface { CreateClusterFlavor(Name string, tx StoreTransaction) (Flavor datatypes.ClusterFlavorPersisted, err error) UpdateClusterFlavor(ID string, Name string, tx StoreTransaction) (err error) MarkClusterFlavorDeleted(ID string, tx StoreTransaction) (err error) DeleteClusterFlavorPermanent(ID string, tx StoreTransaction) (err error) ReadClusterFlavor(ID string) (Flavor datatypes.ClusterFlavorPersisted, err error) ListClusterFlavors(Includedeleted bool) (Flavors []datatypes.ClusterFlavorPersisted, err error) } //Store is the interface to encapsulate the Storage Backend type Store interface { MustBegin() (tx StoreTransaction) CleanupTimestamps ClusterFlavors } Why should I create it in that fashion if I ever use the Store interface in my cod? Or what are the drawbacks if I put all methods needed directly into the Store interface? kind regards Reinhard -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
[go-nuts] if you use sql.NullXYZ, what else do you find yourself doing to make coding easier (or make your code more readable, etc...)
For me it works perfect when I just define each nullable field as a pointer in the struct which represents a da base record. If the struct field is nil it will be null in the database and json encoding handles these fields also correctly -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.