Comments (5)
When I wrote it initially, the Shutdown function for the built-in HTTP server didn't exist, and there is no current equivalent. If you'd like to submit a pull request, I'd be happy to take a look at it.
from smtpd.
from smtpd.
Hello, I'm looking at implementing a graceful shutdown but can't quite get it to work. Here's my code that starts the SMTP listener:
func listenEmail(ctx context.Context, port string) {
srv := &smtpd.Server{
Addr: "0.0.0.0:" + port,
Handler: mailHandler,
Appname: "...",
Hostname: "...",
}
go func() {
<- ctx.Done()
log.Println("We should stop the SMTP server now...")
srv.Close()
log.Println("We closed it")
}()
err := srv.ListenAndServe()
if err != nil {
log.Fatal("Unable to start smtp server: ", err)
os.Exit(1)
}
log.Println("listenEmail goroutine quits")
}
Not shown here, but on Ctrl+C, ctx
gets cancelled, so the inner goroutine runs and calls srv.Close()
. When I run this, the "We closed it" message from the inner goroutine gets printed, but the final "listenEmail goroutine quits" does not. I assume that's because ListenAndServe
still keeps blocking.
I was looking at the smtpd source code:
// Serve creates a new SMTP session after a network connection is established.
func (srv *Server) Serve(ln net.Listener) error {
if atomic.LoadInt32(&srv.inShutdown) != 0 {
return ErrServerClosed
}
defer ln.Close()
for {
// if we are shutting down, don't accept new connections
select {
case <-srv.getShutdownChan():
return ErrServerClosed
default:
}
conn, err := ln.Accept()
if err != nil {
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
continue
}
return err
}
session := srv.newSession(conn)
atomic.AddInt32(&srv.openSessions, 1)
go session.serve()
}
}
To me it looks like it checks the shutdown condition at the start of the for loop, and then blocks at ln.Accept()
. So, I'm guessing, it needs to receive one extra email for the loop to advance and the Serve
call to return. Does that make sense? I'm a Go novice and am stepping on rakes and making wrong guesses left and right :-)
I also run a HTTP listener (http.Server) in a similar way, and it is able to finish up immediately, without waiting for one extra HTTP request. Perhaps there's a viable way to make smtpd work the same?
from smtpd.
Your analysis makes sense. The Server in the http package has handling for the shutdown after the Accept call which is missing here. Want to have a go at fixing it and sending a pull request?
from smtpd.
I can give it a try, but it would need a thorough review for sure. My knowledge of Go is minimal.
from smtpd.
Related Issues (20)
- Add AUTH support HOT 1
- Support for large emails via smart disk buffering? HOT 9
- sending Email HOT 1
- Too many recipients HOT 1
- How can I sign an outgoing email with DKIM? HOT 1
- [Question] Suitable for receiving incoming mail from the wider web? HOT 6
- From and To addresses with leading spaces HOT 3
- Save state after authentication HOT 8
- Adding go.mod and tagging release? HOT 2
- Wrong operator used? HOT 1
- Fix go.mod HOT 3
- Example not working HOT 3
- On shutdown, smtpd waits for one more message before shutting down
- how to send email? HOT 4
- Possibility to publish a version HOT 2
- how to get the body of the email? HOT 2
- A minimum of 100 Users have to be allowed. so > 100 can be dropped
- tls support HOT 3
- Feature request: Connection Timeout HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from smtpd.