Re: [go-nuts] Should we stop using a global logger?

2017-08-24 Thread Peter Mogensen


On 2017-08-25 08:31, Henrik Johansson wrote:
> How do you code for storing a logger in context.Value? The same usual
> issues with lacking a shared logger interface happens or did I miss
> something neat?
> 

I try not to do logging from libraries. So logging (and the logger
interface) is specific to my application.

Internally I would pass loggers as arguments, but using context.Context
becomes relevant when building a middleware stack. So the application
installs both the middleware creating the logger and the handler using
it. (and they then both know the type).
There can be other application specific request-scoped stuff you want to
pass along down the middleware stack - such as
Authentication-ID/Authorization-ID. So there's ususally an application
specific requestcontext and not just a logger.

/Peter

-- 
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: Should we stop using a global logger?

2017-08-24 Thread Peter Mogensen


On 2017-08-25 05:58, Dave Cheney wrote:
>> Should we stop using a global logger?
> 
> Yes[1]
> 
> 1. https://dave.cheney.net/2017/01/26/context-is-for-cancelation
>

fair point...

It can be very tempting though. Especially dealing with an HTTP
middleware stack where you need handlers to log and automatically add
Req-ID to the logging.
Unless of course, you use a middleware framework designed to make a
logger available.

/Peter

-- 
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] Re: Should we stop using a global logger?

2017-08-24 Thread Dave Cheney


On Friday, 25 August 2017 16:02:48 UTC+10, snmed wrote:
>
> Hi Dave
>
> I've read about this context.Value topic on several occasion and in your 
> blog post you say context is only for cancelation. But how should one cope 
> with real goroutine specific data, unfortunately i missed always a correct 
> solution for this problem.
>

My recommendation is to pass it down from function to function, either as 
an argument, or as fields accessible from a method. 
 

> Any proposal is welcome
>
> Cheers snmed
>
>

-- 
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] Should we stop using a global logger?

2017-08-24 Thread Henrik Johansson
How do you code for storing a logger in context.Value? The same usual
issues with lacking a shared logger interface happens or did I miss
something neat?

On Fri, 25 Aug 2017, 08:26 Peter Mogensen  wrote:

>
>
> On 2017-08-25 05:38, buchanae.o...@gmail.com wrote:
> > - We create a child logger instance which has the ID preconfigured, and
> > pass that to some function calls. [3]
>
> I think several log packages has the feature build in.
>
> > instances everywhere. I think we can make either work, and so far
> > neither is an obvious choice. What do you think?
>
> IMHO ideally, you should use local logger instances. But that of course
> only becomes gradually more relevant the larger and more modularized the
> application becomes.
>
> > A third, interesting option might be to add all logging configuration to
> > the context using context.Value,
>
> I'd prefer this option in many cases. However, I probably wouldn't put
> formatting preferences into context.Value.
>
> A third way to use flexible logging is to have a global logger registry
> like the python "logging" package where each part of the code can
> acquire its logger with GetLogger(name). Loggers are then arranged in a
> hierarchy so you don't have to configure formatting for each individually.
>
> /Peter
>
> --
> 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.
>

-- 
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] Should we stop using a global logger?

2017-08-24 Thread Peter Mogensen


On 2017-08-25 05:38, buchanae.o...@gmail.com wrote:
> - We create a child logger instance which has the ID preconfigured, and
> pass that to some function calls. [3]

I think several log packages has the feature build in.

> instances everywhere. I think we can make either work, and so far
> neither is an obvious choice. What do you think?

IMHO ideally, you should use local logger instances. But that of course
only becomes gradually more relevant the larger and more modularized the
application becomes.

> A third, interesting option might be to add all logging configuration to
> the context using context.Value,

I'd prefer this option in many cases. However, I probably wouldn't put
formatting preferences into context.Value.

A third way to use flexible logging is to have a global logger registry
like the python "logging" package where each part of the code can
acquire its logger with GetLogger(name). Loggers are then arranged in a
hierarchy so you don't have to configure formatting for each individually.

/Peter

-- 
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] Re: Should we stop using a global logger?

2017-08-24 Thread snmed
Hi Dave

I've read about this context.Value topic on several occasion and in your blog 
post you say context is only for cancelation. But how should one cope with real 
goroutine specific data, unfortunately i missed always a correct solution for 
this problem.

Any proposal is welcome

Cheers snmed

-- 
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] Go 1.9 poller, close os.File used by another goroutine

2017-08-24 Thread Dave Cheney
If that file is a pipe, yes.
If that file is not a pipe, no, it's still not possible because POSIX doesn't 
give those guarnetees without using non blocking IO.

-- 
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] Go 1.9 poller, close os.File used by another goroutine

2017-08-24 Thread Dave Keck
Hey all,

With Go 1.9's use of the poller for file I/O, I'd like to use f.Close() to
make another goroutine exit if it's blocked on a read or write. Is that
safe in Go 1.9? (Currently I'm using a kqueue to safely handle such
teardown.)

Thanks!
David

-- 
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] Re: can't open file if its name was read from stdin

2017-08-24 Thread Uli Kunitz
ReadString returns the line including the terminating newline ('\n'). You 
can check it with fmt.Printf("filename: %q\n", filename). One option to fix 
it is using function strings.TrimSpace. It will remove all space characters 
at the start and the end of the string. 

-- 
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] Should we stop using a global logger?

2017-08-24 Thread Tamás Gulácsi
Yes[1]: your logger is a concrete dependency which should be passed explicitly 
to the function which logs!

And as the common idiom is to not include Context in struct but pass as the 
first argument, the logger should be inserted into that Context.

[1] 
https://peter.bourgon.org/go-best-practices-2016/#logging-and-instrumentation

-- 
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] can't open file if its name was read from stdin

2017-08-24 Thread Dave Cheney
Check the error from ReadString to find out why it's returning a empty string. 

-- 
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] Re: Should we stop using a global logger?

2017-08-24 Thread buchanae . ohsu
Or, what if...


type FunnelContext interface {
  context.Context
  logger.Logger
}

type RequestHandler struct {
  // No context specific fields here, instance stays reusable across 
requests
}
func (RequestHandler) Handle(ctx FunnelContext) {}

 



On Thursday, August 24, 2017 at 8:58:15 PM UTC-7, Dave Cheney wrote:
>
> > Should we stop using a global logger?
>
> Yes[1]
>
> 1. https://dave.cheney.net/2017/01/26/context-is-for-cancelation
>
> On Friday, 25 August 2017 13:38:48 UTC+10, buchan...@gmail.com wrote:
>>
>> In Funnel [1], we've been using a global logger, based on logrus [2]. 
>> This has worked fine through the early stages of the project, but it's 
>> starting to show a few cracks. In particular, we need to ensure that a 
>> request (task) ID is present in all log messages. Solutions to this have 
>> grown to be inconsistent:
>>
>> - We create a child logger instance which has the ID preconfigured, and 
>> pass that to some function calls. [3]
>> - We're looking at passing a context to logging calls, and the logger 
>> pulls the ID from context.Value. [4]
>> - Some calls have been left behind and are still using the global logger.
>>
>> Other notes:
>> - A global logger configured to a single task ID won't work, since 
>> multiple requests may be handled concurrently.
>> - Request handling spans multiple packages.
>> - We're using context extensively, we're ok with using it more.
>>
>> We're trying to decide whether to stick to a global (singleton) logger, 
>> or remove the global logger completely and start passing logger instances 
>> everywhere. I think we can make either work, and so far neither is an 
>> obvious choice. What do you think?
>>
>> Global logger:
>> - seems to be the most common approach
>> - convenient access
>> - global singleton might lead to difficulty and inflexibility, e.g. 
>> capturing logging in tests, multiple configurations
>>
>> Logger instances:
>> - more fields on every type and function that wants to log
>> - full control over logging in each individual type and function
>> - clearly stated dependencies for each type/function. I'd say Go idioms 
>> tend toward obvious, clear, and powerful over clean, concise, magic.
>>
>> A third, interesting option might be to add all logging configuration to 
>> the context using context.Value, including output, formatting, etc. Global 
>> logging functions would pull all needed config from the context. I'm 
>> worried this gets into the hotly debated territory of abusing 
>> context.Value. On the other hand, we're already passing context everywhere, 
>> and this is useful context that crosses API boundaries.
>>
>> Anywho, would love to get thoughts from the experts out there. Thanks for 
>> reading!
>>
>> Alex
>>
>>
>> [1] https://github.com/ohsu-comp-bio/funnel
>> [2] https://github.com/sirupsen/logrus
>> [3] 
>> https://github.com/ohsu-comp-bio/funnel/blob/master/worker/runner.go#L25
>> [4] https://github.com/ohsu-comp-bio/funnel/pull/194
>>
>

-- 
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: [ANN] Gomail v2: sending emails faster

2017-08-24 Thread Antonio Sun
You should break that 40s up and see how long is spent on dial, and how
long is spent on send.

On Thu, Aug 24, 2017 at 9:41 PM,  wrote:

> Thank you very much for your reply. However, in my code, it spent 40s to
> send email.
>
> Here is the code:
>
> now := time.Now()
> msg := gomail.NewMessage()
> //the element of msg is abridged
> dial := gomail.Dialer{Host: "127.0.0.1", Port: 25}
> dial.TLSConfig = &tls.Config{InsecureSkipVerify: true}
> if err := dial.DialAndSend(msg); err != nil {
> log.Fatal("failed to send email", err)
> } else {
> timeSpent := fmt.Sprintf("%.3f s", time.Since(now).Seconds())
> fmt.Println("time to spend in sending email", timeSpent )
> }
>
> 在 2017年8月25日星期五 UTC+8上午1:53:48,Tamás Gulácsi写道:
>
>> It uses a constant 10s timeout for dial. What should time out?
>
> --
> 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/jMxZHzvvEVg/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> golang-nuts+unsubscr...@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.


[go-nuts] Re: Should we stop using a global logger?

2017-08-24 Thread Dave Cheney
> Should we stop using a global logger?

Yes[1]

1. https://dave.cheney.net/2017/01/26/context-is-for-cancelation

On Friday, 25 August 2017 13:38:48 UTC+10, buchan...@gmail.com wrote:
>
> In Funnel [1], we've been using a global logger, based on logrus [2]. This 
> has worked fine through the early stages of the project, but it's starting 
> to show a few cracks. In particular, we need to ensure that a request 
> (task) ID is present in all log messages. Solutions to this have grown to 
> be inconsistent:
>
> - We create a child logger instance which has the ID preconfigured, and 
> pass that to some function calls. [3]
> - We're looking at passing a context to logging calls, and the logger 
> pulls the ID from context.Value. [4]
> - Some calls have been left behind and are still using the global logger.
>
> Other notes:
> - A global logger configured to a single task ID won't work, since 
> multiple requests may be handled concurrently.
> - Request handling spans multiple packages.
> - We're using context extensively, we're ok with using it more.
>
> We're trying to decide whether to stick to a global (singleton) logger, or 
> remove the global logger completely and start passing logger instances 
> everywhere. I think we can make either work, and so far neither is an 
> obvious choice. What do you think?
>
> Global logger:
> - seems to be the most common approach
> - convenient access
> - global singleton might lead to difficulty and inflexibility, e.g. 
> capturing logging in tests, multiple configurations
>
> Logger instances:
> - more fields on every type and function that wants to log
> - full control over logging in each individual type and function
> - clearly stated dependencies for each type/function. I'd say Go idioms 
> tend toward obvious, clear, and powerful over clean, concise, magic.
>
> A third, interesting option might be to add all logging configuration to 
> the context using context.Value, including output, formatting, etc. Global 
> logging functions would pull all needed config from the context. I'm 
> worried this gets into the hotly debated territory of abusing 
> context.Value. On the other hand, we're already passing context everywhere, 
> and this is useful context that crosses API boundaries.
>
> Anywho, would love to get thoughts from the experts out there. Thanks for 
> reading!
>
> Alex
>
>
> [1] https://github.com/ohsu-comp-bio/funnel
> [2] https://github.com/sirupsen/logrus
> [3] 
> https://github.com/ohsu-comp-bio/funnel/blob/master/worker/runner.go#L25
> [4] https://github.com/ohsu-comp-bio/funnel/pull/194
>

-- 
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] Should we stop using a global logger?

2017-08-24 Thread buchanae . ohsu
In Funnel [1], we've been using a global logger, based on logrus [2]. This 
has worked fine through the early stages of the project, but it's starting 
to show a few cracks. In particular, we need to ensure that a request 
(task) ID is present in all log messages. Solutions to this have grown to 
be inconsistent:

- We create a child logger instance which has the ID preconfigured, and 
pass that to some function calls. [3]
- We're looking at passing a context to logging calls, and the logger pulls 
the ID from context.Value. [4]
- Some calls have been left behind and are still using the global logger.

Other notes:
- A global logger configured to a single task ID won't work, since multiple 
requests may be handled concurrently.
- Request handling spans multiple packages.
- We're using context extensively, we're ok with using it more.

We're trying to decide whether to stick to a global (singleton) logger, or 
remove the global logger completely and start passing logger instances 
everywhere. I think we can make either work, and so far neither is an 
obvious choice. What do you think?

Global logger:
- seems to be the most common approach
- convenient access
- global singleton might lead to difficulty and inflexibility, e.g. 
capturing logging in tests, multiple configurations

Logger instances:
- more fields on every type and function that wants to log
- full control over logging in each individual type and function
- clearly stated dependencies for each type/function. I'd say Go idioms 
tend toward obvious, clear, and powerful over clean, concise, magic.

A third, interesting option might be to add all logging configuration to 
the context using context.Value, including output, formatting, etc. Global 
logging functions would pull all needed config from the context. I'm 
worried this gets into the hotly debated territory of abusing 
context.Value. On the other hand, we're already passing context everywhere, 
and this is useful context that crosses API boundaries.

Anywho, would love to get thoughts from the experts out there. Thanks for 
reading!

Alex


[1] https://github.com/ohsu-comp-bio/funnel
[2] https://github.com/sirupsen/logrus
[3] https://github.com/ohsu-comp-bio/funnel/blob/master/worker/runner.go#L25
[4] https://github.com/ohsu-comp-bio/funnel/pull/194

-- 
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] can't open file if its name was read from stdin

2017-08-24 Thread buzzersdad
Does anyone know why Google Go program 1 works, below, and program 2 
doesn't? The only difference - I read in the filename from the console in 
the one that doesn't work but it is a literal in the one that works... I 
tried typing in the full path for the file, and also "..sample.txt" instead 
of "sample.txt", but they didn't solve it either.
// program 1 - this works:

package main import (
"fmt"
"os"
"bufio" )

func main() { 
filename := getFilename()
fmt.Println("opening:",filename) 
//  fmt.Println("opening:sample.txt") 
_ , err := os.Open("sample.txt") 
//   _ , err := os.Open(filename) 
if err != nil { 
panic(err) 
} 
} 

func getFilename()  string {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter file name: ")// type in anything, this file 
name not used
filename, _ := reader.ReadString('\n')
return filename
}


// program 2 - this doesn't work, gives error shown below:

package main
import (
"fmt"
"os"
"bufio"
)

func main() 
filename := getFilename()
fmt.Println("opening:",filename)
// fmt.Println("opening: sample.txt")
// _ , err := os.Open("sample.txt")
_ , err := os.Open(filename)
if err != nil {
panic(err)
}
}

func getFilename()  string {
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter file name: ")// type in "sample.txt" (without 
the quotes)
filename, _ := reader.ReadString('\n')
return filename
}

Error message, panic invoked - 
: The filename, directory name, or volume label syntax is incorrect.

goroutine 1 [running]:
main.main()
C:/installed programs/go/src/testopen2.go:16 +0x158
exit status 2

-- 
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] Re: [ANN] Gomail v2: sending emails faster

2017-08-24 Thread yhj772709
Thank you very much for your reply. However, in my code, it spent 40s to 
send email. 

Here is the code:

now := time.Now()
msg := gomail.NewMessage()
//the element of msg is abridged
dial := gomail.Dialer{Host: "127.0.0.1", Port: 25}
dial.TLSConfig = &tls.Config{InsecureSkipVerify: true}
if err := dial.DialAndSend(msg); err != nil {
log.Fatal("failed to send email", err)
} else {
timeSpent := fmt.Sprintf("%.3f s", time.Since(now).Seconds())
fmt.Println("time to spend in sending email", timeSpent )
}

在 2017年8月25日星期五 UTC+8上午1:53:48,Tamás Gulácsi写道:
>
> It uses a constant 10s timeout for dial. What should time out?

-- 
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: Go 1.9 is released

2017-08-24 Thread jimmy frasche
Thanks for all the great work—lots of exciting changes in this release!

On Thu, Aug 24, 2017 at 3:52 PM, Nathan Kerr  wrote:
> Congrats!
>
> I updated my Go Release Timeline and When Should You Upgrade Go? pages.
>
> On Friday, August 25, 2017 at 12:44:25 AM UTC+2, Chris Broadfoot wrote:
>>
>> Hello gophers,
>>
>> We just released Go 1.9.
>>
>> You can read the announcement blog post here:
>>   https://blog.golang.org/go1.9
>>
>> You can download binary and source distributions from our download page:
>>   https://golang.org/dl/
>>
>> To compile from source using a Git checkout, update to the release with
>> "git checkout go1.9" and build as usual.
>>
>> To find out what has changed, read the release notes:
>>   https://golang.org/doc/go1.9
>>
>> Thanks to everyone who contributed to the release.
>>
>> Chris
>
> --
> 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.

-- 
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] Re: Go 1.9 is released

2017-08-24 Thread Nathan Kerr
Congrats!

I updated my Go Release Timeline 
 and When Should You 
Upgrade Go?  pages.

On Friday, August 25, 2017 at 12:44:25 AM UTC+2, Chris Broadfoot wrote:
>
> Hello gophers,
>
> We just released Go 1.9.
>
> You can read the announcement blog post here:
>   https://blog.golang.org/go1.9
>
> You can download binary and source distributions from our download page:
>   https://golang.org/dl/
>
> To compile from source using a Git checkout, update to the release with 
> "git checkout go1.9" and build as usual.
>
> To find out what has changed, read the release notes:
>   https://golang.org/doc/go1.9
>
> Thanks to everyone who contributed to the release.
>
> Chris
>

-- 
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] Go 1.9 is released

2017-08-24 Thread Chris Broadfoot
Hello gophers,

We just released Go 1.9.

You can read the announcement blog post here:
  https://blog.golang.org/go1.9

You can download binary and source distributions from our download page:
  https://golang.org/dl/

To compile from source using a Git checkout, update to the release with
"git checkout go1.9" and build as usual.

To find out what has changed, read the release notes:
  https://golang.org/doc/go1.9

Thanks to everyone who contributed to the release.

Chris

-- 
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] Potential race condition in prototypical network server code

2017-08-24 Thread Tom Payne
Ah, cool. So graceful shutdown can be achieved by calling Close() on the 
net.Listener. Nice!

Thank you :)

Tom


On Thursday, August 24, 2017 at 8:20:34 PM UTC+2, Jan Mercl wrote:
>
> net.Listener has a Close method that will make Accept return an error. 
> net.Listener.Accept is not equal to accept(2).
>
> On Thu, Aug 24, 2017, 20:13 Tom Payne > 
> wrote:
>
>> Thanks. Looking at the man page for Linux's accept(2) 
>> http://man7.org/linux/man-pages/man2/accept.2.html it seems that 
>> l.Accept is unlikely to ever return an error.
>>
>> accept(2) returns an error if either the connection is incorrectly set up 
>> somehow, or if a system call is interrupted by a signal, or if the process 
>> or system runs out of resources (either file handles or memory).
>>
>> Setup problems should occur immediately (before any client connection is 
>> actually accepted) so there is no race there. It looks to me that EINTR is 
>> *not* handled by Go's runtime so real world (not prototypical) server code 
>> needs to handle EINTR, but there is no race condition in the code (in the 
>> case of a signal, the function will terminate without leaking resources). 
>> In the case of resource exhaustion it's hard to implement sane behaviour in 
>> any case.
>>
>> Thanks again for the discussion - I'm learning a lot here. Is there 
>> anything above that is not correct?
>>
>> Cheers,
>> Tom
>>
>>
>> On Thursday, August 24, 2017 at 7:56:22 PM UTC+2, Jan Mercl wrote:
>>
>>> The wg.Wait will be executed after l.Accept returns an error. It's 
>>> purpose is to wait for the completions of all handlers invoked in the go 
>>> statement that did not finished already.
>>>
>>> On Thu, Aug 24, 2017, 19:49 Tom Payne  wrote:
>>>
 Awesome, thanks Jan for the fast and clear response.

 In fact, the for {} is an infinite loop so wg.Wait() will never be 
 reached and serve() will never terminate. Correct?

 I guess I over-read how much this prototypical code was representative 
 of a real server loop. Sorry Dave!

 Tom

 On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:

> No, wg.Add cannot "switch" to wg.Wait, they're both in the samr 
> goroutine, the go statement will be always the next one to execute after 
> wg.Add within serve().
>
> On Thu, Aug 24, 2017, 19:29 Tom Payne  wrote:
>
 I'm not singling out Dave Cheney here, I'd just like to check my 
>> understanding of Go's resource handling and concurrency.
>>
>> In this blog post a "prototypical network server" is presented:
>>
>>https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>>
>> Code:
>>
>> func serve(l net.Listener) error {
>> var wg sync.WaitGroup
>> var conn net.Conn
>> var err error
>> for {
>> conn, err = l.Accept()
>> if err != nil {
>> break
>> }
>> wg.Add(1)
>> go func(c net.Conn) {
>> defer wg.Done()
>> handle(c)
>> }(conn)
>> }
>> wg.Wait()
>> return err
>> }
>>
>> My understanding is that this contains a race condition. 
>> Specifically, a goroutine switch can occur at the entry to wg.Add(1), 
>> switching to wg.Wait() in the main goroutine. At this point, a 
>> connection 
>> has been accepted, but the WaitGroup counter has not been incremented, 
>> so 
>> the serve function will terminate while silently dropping a network 
>> connection (the connection will be accepted, but never handled, so will 
>> probably eventually time out on the client side and leak a file 
>> descriptor 
>> on the server side).
>>
>> Is this understanding correct? Furthermore, I suspect that it's 
>> impossible to implement race-free graceful termination using only 
>> sync.WaitGroups. Is it actually possible to do so?
>>
>> Thanks for any correction, and apologies to Dave for picking on his 
>> code.
>>
>> Cheers,
>> Tom
>>
>> -- 
>> 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...@googlegroups.com.
>
>
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
>
> -j
>
 -- 
 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...@googlegroups.com.
 For more options, visit https://groups.google.com/d/optout.

>>> -- 
>>>
>>> -j
>>>
>> -- 
>> You received this message because you are subsc

Re: [go-nuts] Potential race condition in prototypical network server code

2017-08-24 Thread Jan Mercl
net.Listener has a Close method that will make Accept return an error.
net.Listener.Accept is not equal to accept(2).

On Thu, Aug 24, 2017, 20:13 Tom Payne  wrote:

> Thanks. Looking at the man page for Linux's accept(2)
> http://man7.org/linux/man-pages/man2/accept.2.html it seems that l.Accept
> is unlikely to ever return an error.
>
> accept(2) returns an error if either the connection is incorrectly set up
> somehow, or if a system call is interrupted by a signal, or if the process
> or system runs out of resources (either file handles or memory).
>
> Setup problems should occur immediately (before any client connection is
> actually accepted) so there is no race there. It looks to me that EINTR is
> *not* handled by Go's runtime so real world (not prototypical) server code
> needs to handle EINTR, but there is no race condition in the code (in the
> case of a signal, the function will terminate without leaking resources).
> In the case of resource exhaustion it's hard to implement sane behaviour in
> any case.
>
> Thanks again for the discussion - I'm learning a lot here. Is there
> anything above that is not correct?
>
> Cheers,
> Tom
>
>
> On Thursday, August 24, 2017 at 7:56:22 PM UTC+2, Jan Mercl wrote:
>
>> The wg.Wait will be executed after l.Accept returns an error. It's
>> purpose is to wait for the completions of all handlers invoked in the go
>> statement that did not finished already.
>>
>> On Thu, Aug 24, 2017, 19:49 Tom Payne  wrote:
>>
>>> Awesome, thanks Jan for the fast and clear response.
>>>
>>> In fact, the for {} is an infinite loop so wg.Wait() will never be
>>> reached and serve() will never terminate. Correct?
>>>
>>> I guess I over-read how much this prototypical code was representative
>>> of a real server loop. Sorry Dave!
>>>
>>> Tom
>>>
>>> On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:
>>>
 No, wg.Add cannot "switch" to wg.Wait, they're both in the samr
 goroutine, the go statement will be always the next one to execute after
 wg.Add within serve().

 On Thu, Aug 24, 2017, 19:29 Tom Payne  wrote:

>>> I'm not singling out Dave Cheney here, I'd just like to check my
> understanding of Go's resource handling and concurrency.
>
> In this blog post a "prototypical network server" is presented:
>
>https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>
> Code:
>
> func serve(l net.Listener) error {
> var wg sync.WaitGroup
> var conn net.Conn
> var err error
> for {
> conn, err = l.Accept()
> if err != nil {
> break
> }
> wg.Add(1)
> go func(c net.Conn) {
> defer wg.Done()
> handle(c)
> }(conn)
> }
> wg.Wait()
> return err
> }
>
> My understanding is that this contains a race condition. Specifically,
> a goroutine switch can occur at the entry to wg.Add(1), switching to
> wg.Wait() in the main goroutine. At this point, a connection has been
> accepted, but the WaitGroup counter has not been incremented, so the serve
> function will terminate while silently dropping a network connection (the
> connection will be accepted, but never handled, so will probably 
> eventually
> time out on the client side and leak a file descriptor on the server 
> side).
>
> Is this understanding correct? Furthermore, I suspect that it's
> impossible to implement race-free graceful termination using only
> sync.WaitGroups. Is it actually possible to do so?
>
> Thanks for any correction, and apologies to Dave for picking on his
> code.
>
> Cheers,
> Tom
>
> --
> 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...@googlegroups.com.


> For more options, visit https://groups.google.com/d/optout.
>
 --

 -j

>>> --
>>> 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...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>>
>> -j
>>
> --
> 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.
>
-- 

-j

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from t

Re: [go-nuts] Potential race condition in prototypical network server code

2017-08-24 Thread Tom Payne
Thanks. Looking at the man page for Linux's 
accept(2) http://man7.org/linux/man-pages/man2/accept.2.html it seems that 
l.Accept is unlikely to ever return an error.

accept(2) returns an error if either the connection is incorrectly set up 
somehow, or if a system call is interrupted by a signal, or if the process 
or system runs out of resources (either file handles or memory).

Setup problems should occur immediately (before any client connection is 
actually accepted) so there is no race there. It looks to me that EINTR is 
*not* handled by Go's runtime so real world (not prototypical) server code 
needs to handle EINTR, but there is no race condition in the code (in the 
case of a signal, the function will terminate without leaking resources). 
In the case of resource exhaustion it's hard to implement sane behaviour in 
any case.

Thanks again for the discussion - I'm learning a lot here. Is there 
anything above that is not correct?

Cheers,
Tom

On Thursday, August 24, 2017 at 7:56:22 PM UTC+2, Jan Mercl wrote:
>
> The wg.Wait will be executed after l.Accept returns an error. It's purpose 
> is to wait for the completions of all handlers invoked in the go statement 
> that did not finished already.
>
> On Thu, Aug 24, 2017, 19:49 Tom Payne > 
> wrote:
>
>> Awesome, thanks Jan for the fast and clear response.
>>
>> In fact, the for {} is an infinite loop so wg.Wait() will never be 
>> reached and serve() will never terminate. Correct?
>>
>> I guess I over-read how much this prototypical code was representative of 
>> a real server loop. Sorry Dave!
>>
>> Tom
>>
>> On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:
>>
>>> No, wg.Add cannot "switch" to wg.Wait, they're both in the samr 
>>> goroutine, the go statement will be always the next one to execute after 
>>> wg.Add within serve().
>>>
>>> On Thu, Aug 24, 2017, 19:29 Tom Payne  wrote:
>>>
>> I'm not singling out Dave Cheney here, I'd just like to check my 
 understanding of Go's resource handling and concurrency.

 In this blog post a "prototypical network server" is presented:

https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation

 Code:

 func serve(l net.Listener) error {
 var wg sync.WaitGroup
 var conn net.Conn
 var err error
 for {
 conn, err = l.Accept()
 if err != nil {
 break
 }
 wg.Add(1)
 go func(c net.Conn) {
 defer wg.Done()
 handle(c)
 }(conn)
 }
 wg.Wait()
 return err
 }

 My understanding is that this contains a race condition. Specifically, 
 a goroutine switch can occur at the entry to wg.Add(1), switching to 
 wg.Wait() in the main goroutine. At this point, a connection has been 
 accepted, but the WaitGroup counter has not been incremented, so the serve 
 function will terminate while silently dropping a network connection (the 
 connection will be accepted, but never handled, so will probably 
 eventually 
 time out on the client side and leak a file descriptor on the server side).

 Is this understanding correct? Furthermore, I suspect that it's 
 impossible to implement race-free graceful termination using only 
 sync.WaitGroups. Is it actually possible to do so?

 Thanks for any correction, and apologies to Dave for picking on his 
 code.

 Cheers,
 Tom

 -- 
 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...@googlegroups.com.
>>>
>>>
 For more options, visit https://groups.google.com/d/optout.

>>> -- 
>>>
>>> -j
>>>
>> -- 
>> 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...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
>
> -j
>

-- 
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] Potential race condition in prototypical network server code

2017-08-24 Thread Jan Mercl
The wg.Wait will be executed after l.Accept returns an error. It's purpose
is to wait for the completions of all handlers invoked in the go statement
that did not finished already.

On Thu, Aug 24, 2017, 19:49 Tom Payne  wrote:

> Awesome, thanks Jan for the fast and clear response.
>
> In fact, the for {} is an infinite loop so wg.Wait() will never be reached
> and serve() will never terminate. Correct?
>
> I guess I over-read how much this prototypical code was representative of
> a real server loop. Sorry Dave!
>
> Tom
>
> On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:
>
>> No, wg.Add cannot "switch" to wg.Wait, they're both in the samr
>> goroutine, the go statement will be always the next one to execute after
>> wg.Add within serve().
>>
>> On Thu, Aug 24, 2017, 19:29 Tom Payne  wrote:
>>
> I'm not singling out Dave Cheney here, I'd just like to check my
>>> understanding of Go's resource handling and concurrency.
>>>
>>> In this blog post a "prototypical network server" is presented:
>>>
>>>https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>>>
>>> Code:
>>>
>>> func serve(l net.Listener) error {
>>> var wg sync.WaitGroup
>>> var conn net.Conn
>>> var err error
>>> for {
>>> conn, err = l.Accept()
>>> if err != nil {
>>> break
>>> }
>>> wg.Add(1)
>>> go func(c net.Conn) {
>>> defer wg.Done()
>>> handle(c)
>>> }(conn)
>>> }
>>> wg.Wait()
>>> return err
>>> }
>>>
>>> My understanding is that this contains a race condition. Specifically, a
>>> goroutine switch can occur at the entry to wg.Add(1), switching to
>>> wg.Wait() in the main goroutine. At this point, a connection has been
>>> accepted, but the WaitGroup counter has not been incremented, so the serve
>>> function will terminate while silently dropping a network connection (the
>>> connection will be accepted, but never handled, so will probably eventually
>>> time out on the client side and leak a file descriptor on the server side).
>>>
>>> Is this understanding correct? Furthermore, I suspect that it's
>>> impossible to implement race-free graceful termination using only
>>> sync.WaitGroups. Is it actually possible to do so?
>>>
>>> Thanks for any correction, and apologies to Dave for picking on his code.
>>>
>>> Cheers,
>>> Tom
>>>
>>> --
>>> 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...@googlegroups.com.
>>
>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>> --
>>
>> -j
>>
> --
> 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.
>
-- 

-j

-- 
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] Re: [ANN] Gomail v2: sending emails faster

2017-08-24 Thread Tamás Gulácsi
It uses a constant 10s timeout for dial. What should time out?

-- 
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] Potential race condition in prototypical network server code

2017-08-24 Thread Tom Payne
Awesome, thanks Jan for the fast and clear response.

In fact, the for {} is an infinite loop so wg.Wait() will never be reached 
and serve() will never terminate. Correct?

I guess I over-read how much this prototypical code was representative of a 
real server loop. Sorry Dave!

Tom

On Thursday, August 24, 2017 at 7:41:59 PM UTC+2, Jan Mercl wrote:
>
> No, wg.Add cannot "switch" to wg.Wait, they're both in the samr goroutine, 
> the go statement will be always the next one to execute after wg.Add within 
> serve().
>
> On Thu, Aug 24, 2017, 19:29 Tom Payne > 
> wrote:
>
>> I'm not singling out Dave Cheney here, I'd just like to check my 
>> understanding of Go's resource handling and concurrency.
>>
>> In this blog post a "prototypical network server" is presented:
>>
>>https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>>
>> Code:
>>
>> func serve(l net.Listener) error {
>> var wg sync.WaitGroup
>> var conn net.Conn
>> var err error
>> for {
>> conn, err = l.Accept()
>> if err != nil {
>> break
>> }
>> wg.Add(1)
>> go func(c net.Conn) {
>> defer wg.Done()
>> handle(c)
>> }(conn)
>> }
>> wg.Wait()
>> return err
>> }
>>
>> My understanding is that this contains a race condition. Specifically, a 
>> goroutine switch can occur at the entry to wg.Add(1), switching to 
>> wg.Wait() in the main goroutine. At this point, a connection has been 
>> accepted, but the WaitGroup counter has not been incremented, so the serve 
>> function will terminate while silently dropping a network connection (the 
>> connection will be accepted, but never handled, so will probably eventually 
>> time out on the client side and leak a file descriptor on the server side).
>>
>> Is this understanding correct? Furthermore, I suspect that it's 
>> impossible to implement race-free graceful termination using only 
>> sync.WaitGroups. Is it actually possible to do so?
>>
>> Thanks for any correction, and apologies to Dave for picking on his code.
>>
>> Cheers,
>> Tom
>>
>> -- 
>> 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...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
> -- 
>
> -j
>

-- 
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] Potential race condition in prototypical network server code

2017-08-24 Thread Jan Mercl
No, wg.Add cannot "switch" to wg.Wait, they're both in the samr goroutine,
the go statement will be always the next one to execute after wg.Add within
serve().

On Thu, Aug 24, 2017, 19:29 Tom Payne  wrote:

> I'm not singling out Dave Cheney here, I'd just like to check my
> understanding of Go's resource handling and concurrency.
>
> In this blog post a "prototypical network server" is presented:
>
>https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation
>
> Code:
>
> func serve(l net.Listener) error {
> var wg sync.WaitGroup
> var conn net.Conn
> var err error
> for {
> conn, err = l.Accept()
> if err != nil {
> break
> }
> wg.Add(1)
> go func(c net.Conn) {
> defer wg.Done()
> handle(c)
> }(conn)
> }
> wg.Wait()
> return err
> }
>
> My understanding is that this contains a race condition. Specifically, a
> goroutine switch can occur at the entry to wg.Add(1), switching to
> wg.Wait() in the main goroutine. At this point, a connection has been
> accepted, but the WaitGroup counter has not been incremented, so the serve
> function will terminate while silently dropping a network connection (the
> connection will be accepted, but never handled, so will probably eventually
> time out on the client side and leak a file descriptor on the server side).
>
> Is this understanding correct? Furthermore, I suspect that it's impossible
> to implement race-free graceful termination using only sync.WaitGroups. Is
> it actually possible to do so?
>
> Thanks for any correction, and apologies to Dave for picking on his code.
>
> Cheers,
> Tom
>
> --
> 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.
>
-- 

-j

-- 
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] Potential race condition in prototypical network server code

2017-08-24 Thread Tom Payne
I'm not singling out Dave Cheney here, I'd just like to check my 
understanding of Go's resource handling and concurrency.

In this blog post a "prototypical network server" is presented:

   https://dave.cheney.net/2017/08/20/context-isnt-for-cancellation

Code:

func serve(l net.Listener) error {
var wg sync.WaitGroup
var conn net.Conn
var err error
for {
conn, err = l.Accept()
if err != nil {
break
}
wg.Add(1)
go func(c net.Conn) {
defer wg.Done()
handle(c)
}(conn)
}
wg.Wait()
return err
}

My understanding is that this contains a race condition. Specifically, a 
goroutine switch can occur at the entry to wg.Add(1), switching to 
wg.Wait() in the main goroutine. At this point, a connection has been 
accepted, but the WaitGroup counter has not been incremented, so the serve 
function will terminate while silently dropping a network connection (the 
connection will be accepted, but never handled, so will probably eventually 
time out on the client side and leak a file descriptor on the server side).

Is this understanding correct? Furthermore, I suspect that it's impossible 
to implement race-free graceful termination using only sync.WaitGroups. Is 
it actually possible to do so?

Thanks for any correction, and apologies to Dave for picking on his code.

Cheers,
Tom

-- 
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] Re: Generics and readability

2017-08-24 Thread mhhcbon
Why would you put generics on a method ?

The syntax you demonstrate is horrible, indeed.

what if generics are type related

type notFinal struct {
   p1 
   p2 
}

func (n notFinal) whatever(in ) string {
   return fmt.Sprintf(in) // anything to interface{}, works.
}

type Final notFinal

Final.whatever(1) // "1"

//notFinal not instantiable, not type assertable



Or func related

type notFinal func(in ) string

func Final notFinal

Final(1) // "1"


That said, ultimately, the more the syntax is parametrized the more complex 
it become. when there are many func signature as you demonstrate, it will 
get worse.

Named type might help, could be vetted too ?

Also 
none of this is as powerful as code gen.
None of those examples are better than interface{}.

On Thursday, August 24, 2017 at 5:14:58 PM UTC+2, JuciÊ Andrade wrote:
>
> A lot of people like Go because code is very readable even for beginners.
>
> func f(x, y int)
>
> f is a function that receives x and y as int parameters, returning 
> nothing. Simple enough.
>
> func f(x, y int) int
>
> f is a function that receives x and y as int parameters, returning yet 
> another int. Fine.
>
> func f(x, y int) (z int, err error)
>
> f is a function that receives x and y as int parameters, returning two 
> values: a first int, that we name z and an error named err. A little bit 
> weird, but ok.
>
> func (r MyType) f(x, y int) (z int, err error)
>
> f is a method for a value of type MyType, henceforth named r, that 
> receives x and y as int parameters, returning two values: a first int, that 
> we name z and an error named err. Definitely not so simple.
>
>  func (r genType1) f(x, y genType2) (z getType2, err 
> error)
>
> You must be kidding. STOP RIGHT THERE!
>
>

-- 
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] Re: Generics and readability

2017-08-24 Thread gary . willoughby
Using D syntax:

func (r MyType) foo(A, B)(x A, y B) (z B, err error) {
...
}

result, _ := MyType.foo!(int, int)(10, 20)

Also, there's no reason why A and B can't be inferred:

result, _ := MyType.foo(10, 20)

It looks alright to me and very useful!


On Thursday, 24 August 2017 16:14:58 UTC+1, JuciÊ Andrade wrote:
>
> A lot of people like Go because code is very readable even for beginners.
>
> func f(x, y int)
>
> f is a function that receives x and y as int parameters, returning 
> nothing. Simple enough.
>
> func f(x, y int) int
>
> f is a function that receives x and y as int parameters, returning yet 
> another int. Fine.
>
> func f(x, y int) (z int, err error)
>
> f is a function that receives x and y as int parameters, returning two 
> values: a first int, that we name z and an error named err. A little bit 
> weird, but ok.
>
> func (r MyType) f(x, y int) (z int, err error)
>
> f is a method for a value of type MyType, henceforth named r, that 
> receives x and y as int parameters, returning two values: a first int, that 
> we name z and an error named err. Definitely not so simple.
>
>  func (r genType1) f(x, y genType2) (z getType2, err 
> error)
>
> You must be kidding. STOP RIGHT THERE!
>
>

-- 
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] Re: "go get -u" and branch behavior on go1.6

2017-08-24 Thread Tong Sun


On Thursday, March 3, 2016 at 2:47:55 PM UTC-5, Garrett Heel wrote:
>
>
> Is there some alternative way of doing this which supports fetching 
> dependencies from a branch?
>

If you need to *go get from branch*, use 

http://gopkg.in 


-- 
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] Reading bytes into uint32

2017-08-24 Thread Christian von Kietzell
I've read that post and I agree. I can only speculate that they designed
the API that way either because of premature optimisation - saving the
underlying binary from potentially having to swap the byte order - or
out of laziness and an assumption that it's easy to read four bytes
into an int in whatever programming language is used.


Chris

On Thu, Aug 24, 2017 at 06:56:38AM +1000, Rob Pike wrote:
> I know the use of native byte order didn't come from you, but that's
> lazy and wrong.
> 
> https://commandcenter.blogspot.com/2012/04/byte-order-fallacy.html
> 
> -rob
> 
> 
> On Thu, Aug 24, 2017 at 12:12 AM, Wojciech S. Czarnecki  
> wrote:
> > On Wed, 23 Aug 2017 10:51:25 +0200
> > Christian von Kietzell  wrote:
> >
> >> [*1] The data comes from a web browser extension using the native
> >> messaging API, which specifies that messages sent to external programs
> >> are prefixed with the 32-bit length of the message in native byte order.
> >
> > I understand that 'native bo' in this context means 'remote client side
> > endianess'. If so the safest way is to parse incoming request headers,
> > guess byte order from that and tag data as appropriate.
> >
> > If it meant just local2local (local browser talking over lo/pipe)
> > may simply compile endianess variants according to GOARCH.
> >
> > https://godoc.org/go/build#hdr-Build_Constraints
> >
> > --
> > Wojciech S. Czarnecki
> >  << ^oo^ >> OHIR-RIPE
> >
> > --
> > 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.
> 
> -- 
> 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.

-- 
Nothing to see here. Move along.

-- 
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: Reading bytes into uint32

2017-08-24 Thread Christian von Kietzell
Thanks rob,

that works, although I would have prefered a solution without unsafe. I
found a thread from a few years back where someone proposed adding
NativeEndian to encoding/binary which would always do the right thing.
Too bad that never got anywhere.


Chris

On Thu, Aug 24, 2017 at 08:40:12AM +1000, Rob Pike wrote:
> Apologies, typo. This is it: https://play.golang.org/p/9XWoCiUH2D
> 
> On Thu, Aug 24, 2017 at 8:39 AM, Rob Pike  wrote:
> > I believe there is no safe (that is, unsafe-free) way to discover the
> > native byte order. In a sense, this is because depending on the native
> > byte order is intrinsically unsafe. It is by definition not portable.
> > It is a terrible design decision.
> >
> > By the way, that program may work but it's not sound. It has a hidden
> > assumption about how bytes are laid out in arrays and the
> > correspondence with words. (Some machines, like the PDP-11, actually
> > confused some matters like this). This is a better way to discover the
> > byte order, at which point you can use portable methods from
> > encoding/binary: https://play.golang.org/p/7svQ66wl7I
> >
> > -rob
> >
> > On Thu, Aug 24, 2017 at 8:24 AM,   wrote:
> >> It use unsafe, but works even in playground:
> >> https://play.golang.org/p/S1rw157M9C
> >>
> >>
> >> On Wednesday, August 23, 2017 at 3:49:39 PM UTC+3, Christian von Kietzell
> >> wrote:
> >>>
> >>> Hi,
> >>>
> >>> I've stumbled across a problem I don't know how to solve.
> >>>
> >>> I'm trying to read (from stdin) four bytes into a uint32 value. Those
> >>> bytes are provided in _native_ byte order by an external program.[*1]
> >>>
> >>> Since I've found nothing in the standard library to determine the
> >>> machine's native byte order I can't decide whether to use
> >>> binary.BigEndian.Uint32 or binary.LittleEndian.Uint32.
> >>>
> >>> Is there a way without involving package unsafe? Am I missing something
> >>> obvious?
> >>>
> >>> [*1] The data comes from a web browser extension using the native
> >>> messaging API, which specifies that messages sent to external programs
> >>> are prefixed with the 32-bit length of the message in native byte order.
> >>>
> >>>
> >>> Thanks,
> >>> Chris
> >>>
> >>> --
> >>> Nothing to see here. Move along.
> >>
> >> --
> >> 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.

-- 
Nothing to see here. Move along.

-- 
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] Simple url shortener service

2017-08-24 Thread Lutz Horn

Hi,

Am 23.08.2017 um 23:12 schrieb doug...@cornershopapp.com:
i have created a simple url shortener service, for practice and learn 
with go, what do you think !


https://github.com/douglasmakey/ursho


It looks like implementing an URL shortener is a natural choice for 
wetting your toes with Go. I've done something very similar: 
https://github.com/lutzhorn/shorturl


My project adds a simple web GUI, uses http://hashids.org/ instead of DB 
row IDs, and sends an email about a newly inserted URL.


Your project has a nice structure. Especially separation of into 
packages and the use of `base.go` are good ideas. Creating the table 
from code makes deployment easier.


Did you think about using DB transactions, for example in `Load`?

Lutz

--
Lassen Sie uns unsere E-Mails verschlüsseln! So geht's:
https://emailselfdefense.fsf.org/de/
Meinen öffentlichen Schlüssel finden Sie hier:
https://www.lhorn.de/0xC52DFC3A.asc

--
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] Golang TDD CRUD REST API

2017-08-24 Thread Derrick Katungi
Hello, I have been looking for tutorials on Golang TDD Rest API but I have 
not been finding any.
Am not interested in using a framework.

Am interested in a TDD CRUD REST API.

The test I have written returns
controllers/admin.go:18: undefined: a in a.DB

This is what I have so far.
controller/admin.go
func CreateAdmin(w http.ResponseWriter, r *http.Request) {
var admin models.Admin
decoder := json.NewDecoder(r.Body)
if err := decoder.Decode(&admin); err != nil {
helpers.RespondWithError(w, http.StatusBadRequest, "Invalid request 
payload")
return
}
defer r.Body.Close()
if err := admin.CreateAdmin(a.DB); err != nil {
helpers.RespondWithError(w, http.StatusInternalServerError, err.Error())
return
}
helpers.RespondWithJSON(w, http.StatusCreated, admin)
}

model/admin.go
type Admin struct {
IDint `json:"id"`
Name  string  `json:"name"`
Company string `json:"company"`
Username string `json:"username"`
Password string `json:"password"`
}

func (p *Admin) CreateAdmin(db *sql.DB) error {
err := db.QueryRow("INSERT INTO admins(name, company, username, password) 
VALUES($1, $2, $3, $4) RETURNING id", p.Name, p.Company, p.Username, 
p.Password).Scan(&p.ID)

if err != nil {
return err
}

return nil
}

main.go
func main() {
router := mux.NewRouter()

// admin routes
router.HandleFunc("/admin", controllers.CreateAdmin).Methods("GET")
log.Fatal(http.ListenAndServe(":9000", router))
}

tests/admin_test.go
func TestCreateAdmin(t *testing.T) {
payload := []byte(`{"name":"new admin", "company":"localhost", 
"username":"ad...@localhost.com", "password":"admin"}`)

request, err := http.NewRequest("POST", "/admin", bytes.NewBuffer(payload))

if err != nil {
t.Fatal(err)
}

recorder := httptest.NewRecorder()
handler := http.HandlerFunc(controllers.CreateAdmin)
handler.ServeHTTP(recorder, request)

if recorder.Code != http.StatusOK {
t.Errorf("bad response code, wanted %v got %v", recorder.Code, 
http.StatusOK)
}
}

-- 
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] Re: [ANN] Gomail v2: sending emails faster

2017-08-24 Thread yhj772709
Hi, 
Could you show me a method to set timeout when send a email?
Regards.

在 2015年9月2日星期三 UTC+8下午7:55:26,Alexandre Cesaro写道:
>
> Hi,
>
> I just released the second version of Gomail 
> .
>
> There are quite a few backward-incompatible changes 
>  since 
> Gomail v1 but it brings lots of good stuff:
>
>- A great focus was placed on performances. Gomail v2 is way more 
>efficient than Gomail v1 to send a large number of emails (see the 
>Daemon  
>or Newsletter 
> 
>examples).
>- The API is now clearer and way more flexible.
>- The documentation  improved 
>and many examples were added.
>- All existing issues have been closed.
>- The minimum Go version is now 1.2 instead of 1.3. No external 
>dependencies are used with Go 1.5.
>
> More info on Github: https://github.com/go-gomail/gomail
>

-- 
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] Generics and readability

2017-08-24 Thread ojucie
A lot of people like Go because code is very readable even for beginners.

func f(x, y int)

f is a function that receives x and y as int parameters, returning nothing. 
Simple enough.

func f(x, y int) int

f is a function that receives x and y as int parameters, returning yet 
another int. Fine.

func f(x, y int) (z int, err error)

f is a function that receives x and y as int parameters, returning two 
values: a first int, that we name z and an error named err. A little bit 
weird, but ok.

func (r MyType) f(x, y int) (z int, err error)

f is a method for a value of type MyType, henceforth named r, that receives 
x and y as int parameters, returning two values: a first int, that we name 
z and an error named err. Definitely not so simple.

 func (r genType1) f(x, y genType2) (z getType2, err 
error)

You must be kidding. STOP RIGHT THERE!

-- 
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] Understanding "scheduler latency profile" charts

2017-08-24 Thread Konstantin Khomoutov
Hi!

We're trying to investigate a case of pathological behaviour of one of
one HTTP services (built with Go 1.8) under heavy load.

The current hypothesis is that under the load being considered,
the scheduler (or the set of available Ps) have hard time serving that
load.  We came to this conclusion by recording the runtime trace and
then analyzing the delays between the pairs of linked events "a goroutine
is unblocked by the netpoller" and "that goroutine starts executing"
(these delays in our case peak to as much as 3-5 seconds).

To verify our observations, we've decided to try looking at the
"scheduler latency profile" which can be obtained from the runtime
trace -- something like:

  $ go tool trace -pprof=sched runtime.trace >sched.pprof
  $ go tool pprof -evince https://groups.google.com/d/optout.


sched.dot.gz
Description: application/gzip


sched.svg.gz
Description: application/gzip


[go-nuts] Re: Next generation code generator for go

2017-08-24 Thread Walter Schulze
The concurrency promises have been delivered.
The concurrency functions `applicative do` and `pipeline` have been pushed.

On Wednesday, 23 August 2017 19:31:40 UTC+2, Walter Schulze wrote:
>
> https://news.ycombinator.com/item?id=15083381
>
> On Wednesday, 23 August 2017 18:00:49 UTC+2, Walter Schulze wrote:
>>
>> Thank you very much for the compliments and support.
>> I really appreciate it.
>>
>> On Wednesday, 23 August 2017 16:35:29 UTC+2, mhh...@gmail.com wrote:
>>>
>>> coolest repo to watch at that moment
>>>
>>> On Wednesday, August 23, 2017 at 9:38:42 AM UTC+2, Walter Schulze wrote:

 I created gogoprotobuf, but I wanted to create a new code generator for 
 go that does not only work for protocol buffers, but for all go types.

 Here is my next generation code generation for go:
 https://github.com/awalterschulze/goderive
 goderive parses your go code for functions which are not implemented 
 and then generates these functions for you by deriving their 
 implementations from the parameter types.

 These functions includes:
   - recursive functions like GoString and CopyTo
   - functions for sets like Contains and Union and 
   - functions from functional programming like Filter, Fmap and Compose 
 (monad)
   - future: concurrent functions like applicative Do (from haxl)

 Use cases:
   - More maintainable code
   - Experience or experiment with what it would be like to use generic 
 functions in Go ... today.
   - Create user stories for Go 2 in favour of or against generics.
   - Don't argue about using labels and gotos, instead of just writing a 
 contains function.
   - Do functional programming in go.  Well only partly because 
 mutability is still a thing.
   - Less typing of: `if err != nil return err`. The compose function 
 implements monadic error handling.
   - future: less error prone concurrency.

 Ready for production and experimentation.



-- 
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] Re: Simple url shortener service

2017-08-24 Thread mhhcbon
hi and welcome!

At first, it looks like you did not use a *go aware IDE*.
Despite its apparent simplicity, the go language uses a lot of tooling to 
achieve the goal of ~~quality~~.
https://github.com/golang/go/wiki/IDEsAndTextEditorPlugins
https://github.com/golang/go/wiki/CodeTools

You might want to use those tools in future
https://goreportcard.com/report/github.com/douglasmakey/ursho
https://godoc.org/github.com/douglasmakey/ursho
https://godoc.org/golang.org/x/tools/cmd/godoc

Note that you can add their badges to your readme, its good for readers, 
it adds a bit of color and give him some overall before he digs the code.
https://raw.githubusercontent.com/DATA-DOG/go-sqlmock/master/README.md

About database, it worth to mention this package
https://github.com/go-gorp/gorp

In my opinion, a sqlite database, as default, is more suitable for sharing.

You might take advantage of cli flags to enhance a bit the options of the 
bin,
https://golang.org/pkg/flag/

As you do use a dependency manager, might be glide or dep 
https://github.com/golang/dep/
i suggest to always add a ci to your repo and enable it, the point is to 
ensure that the dependencies are complete and working.

Its easy to import a dependency from GOPATH and forget to manage it in the 
dependencies tree.
I had a very similar issue yesterday 
(https://travis-ci.org/mh-cbon/go-msi/builds / 
https://github.com/mh-cbon/go-msi/commit/01538f725f0685ccc711b9f64b5ce2e2426cd321),
 
the CI helped me to find out about it.

small mistake in https://github.com/douglasmakey/ursho/tree/master/enconding
unless i missed something.

This is hard
https://github.com/douglasmakey/ursho/blob/master/handlers/base.go#L21

Panic during init sequence is bad practice. In that case instead of using 
functions,
you could have created a sort of http service with an init method like you 
did
for the database at 
https://github.com/douglasmakey/ursho/blob/master/storages/postgres.go#L18

This looks superfluous, imho,
https://github.com/douglasmakey/ursho/blob/master/main.go#L47
All this code and complexity to close the http server, in that case,
does not add value.
Also, its reading is surprising (twice listenAndServe ? duplication of 
close<-true)
If you was looking for a topic to play with chan/data races, 
i suggest to make the data layer a service, and create an in memory store,
you can do it using chan or mutex.

You have not included any test, hope this helps,
https://elithrar.github.io/article/testing-http-handlers-go/
https://github.com/DATA-DOG/go-sqlmock

On Wednesday, August 23, 2017 at 11:31:15 PM UTC+2, 
dou...@cornershopapp.com wrote:
>
> i have created a simple url shortener service, for practice and learn with 
> go, what do you think ! 
>
> https://github.com/douglasmakey/ursho
>

-- 
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 does assigning a function variable to a method value allocate memory?

2017-08-24 Thread Bakul Shah
On Thu, 24 Aug 2017 07:40:21 BST roger peppe  wrote:
> On 24 August 2017 at 06:39, Bakul Shah  wrote:
> >
> > Finally, for better performance it may make sense to store the
> > FSM as a vector of vectors or vector of maps so that a slice
> > of inputs may be processed in one function call. Probably best
> > done with a FSM generator.
> 
> That's interesting. What might that look like?

Something like this:

type state struct {
nextbyte
action  byte
}

type Token struct {
text[]byte
kindbyte
}

type Scanner struct {
st  state
parser  *Parser
token   Token
...
}

const ( err byte = iota, skip, flush, unget, emit... )

var fsm [][]state
var class []byte

func init() {
// initialize classs. e.g. letter for [A-Za-z]
// create the FSM from a more compact spec
}

func (sc* Scanner) Scan(str []byte) {
st := sc.state
p := sc.parser
i := 0
start = 0
for {
if i >= len(str) { break }
b := str[i] // no unicode, just 8 bit chars!
c := class[b]   // map char to a much smaller char-class
st := fsm[st.next][c]
i++
switch st.action&7 {
case err: // handle errors...
case skip: continue
case flush: start = i // e.g. at the end of a comment
case unget: i--; fallthrough
case emit:
sc.token = Token{str[start:i], st.action>>3}
start = i
p.Parse(sc.token)
}
}
sc.state = st
}

Scan is called every time a line is read. When a full token is
recognized, the Parse is called. sc.action is composed of the
recognized terminal if any + next action.

If an extra char had to be read, the action is unget and
then call Parse. The parser in turn may trigger things
downstream when some sematic action has to be taken.

Scan can be called with the contents of a whole file or even a
single byte string. With this structure the mainloop can
poll/select on a number of input connections.

-- 
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.