I think it depends on what your semantic contract is for this interface.

If the caller starts a server with Run(ctx), is it implied that cancelling 
of ctx should stop the running server? If so, ISTM that there is no need 
for a separate Shutdown() method.  (And there would be no need for App and 
Runnable to be different interfaces)

Note that if the caller wanted to be able to signal a shutdown without 
cancelling the overall context, they could have passed in a child context 
<https://pkg.go.dev/context#WithCancel> and cancelled that instead.  
Equally, if the server needs to receive an explicit Shutdown call for 
whatever reason, it can run a goroutine which waits for the ctx to be 
cancelled and then do whatever it would do if Shutdown() were called.

Indeed, I cannot see what Shutdown(ctx context.Context) would actually do. 
What is the purpose of the ctx passed in here? What if the ctx passed to 
Shutdown is different to the one passed to Run?

Another question I have around semantics is: if a server has been shutdown, 
is it permitted to call Run() on it a second time?  You could allow this, 
but it depends on whether Run() does all initialization, or it depends on a 
clean underlying object.

There is also a question as to whether the error result from Shutdown() is 
required - actually, a server might terminate for reasons other than 
Shutdown() being called - and to know when shutdown has finished after 
being requested. In that case, you might want a separate way to signal (a) 
that the server has terminated, and (b) to return the error value. That 
could for example be a channel returned by Run(). If you make it a 
1-element buffered channel then it doesn't matter whether the value is 
consumed or not.

On Thursday, 16 November 2023 at 13:40:37 UTC Grant Zvolský wrote:

> Upon reflection, I would make the following improvements to bring the 
> interfaces closer to Go's philosophical ideals:
>
> * Remove the App interface because it only has one implementation
> * Remove the Named interface because all its usages seem to be replaceable 
> with a package-scoped const
> * Split the Runnable interface into Runner and Shutdowner (inspired by 
> Reader/Writer) with the advice not to use Shutdowner if context-based 
> shutdown is sufficient
>
> Redesigned interfaces:
> ```
> type Runner interface {
>        Run(ctx context.Context) error
> }
>
> // Shutdowner adds a Shutdown method for services whose shutdown procedure 
> needs to be cancellable.
> type Shutdowner interface {
>        Shutdown(ctx context.Context) error
> }
> ```
>

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/c8b86cd8-76f7-4581-b0cc-63798eb5352bn%40googlegroups.com.

Reply via email to