-
Notifications
You must be signed in to change notification settings - Fork 368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More backends refactoring #71
Conversation
…er" and header parser
…er" and header parser
- Hasher decorator - MySQL decorator also fixes a bug with header parsing Todo: redis decorator, cleanup / remove legacy code, finalise interfaces
- Compressor decorator - Header decorator - Redis decorator Other: Moved events to its own package so that they can be used by backend without getting into circular dep. Guerrilla embeds events directly instead of wrapping the function Todo: , cleanup / remove legacy code, finalise interfaces, change processor initialize to use events. Use a channel for backend errors.
…er and shutdowner
- processor lines can configured via config and built during initialization - backend gateway manages creating of processor lines and starting / stopping workers that use these lines - TODO: lots of cleanup, change to allow multiple rcpt to, more comments, test backend shutdown/restart on config reload
This is a huge... YYYYYUGE... backend refactor! The main idea is to break backend processing down to individual, reusable components. In a nutshell, you'll now be able to customize your backend by configuration, like so:
Tokens are separated by a pipe '|'. Each token is a component called a "Processor". When an email is processed, it goes through each component in a line, starting at the left and ending on the right. How's this implemented? Still need to finalize some things, clean up and determine which interfaces / values need to be public. |
- add comments at the start of all processors
- Remove initializers / shutdowners once backend is shutdown - redis processor: propagate close error - mysql processor: propaget close error - add more comments
- Added in type support to Backend's extractConfig func - saveStatus contains queued instead of hash, better semantically - BackendGateway default config if processor_line not present, or save_workers_size not present - added queued id to envelope, a temporary default id is generated too
…reation - Made some symbols public, ie. Service.ExtractConfig, BaseConfig - Envelope: added a NewRreader() function that returns a reader for the processed email - Moved resetting the envelope from client.go to envelope itself. - Added a Reseed() function that seeds the envelope with data at the start of a connection
- rename Service to Svc - rename BackendResult to Result (the package already has the word backend) - rename saveStatus to notifyMsg to better reflect what it does -Rename NewBackendResult to NewResult - add ValidateRcpt method to Backend interface - use private vars where possible - Added the Errors type - Svc.shutdown returns Errors - Svc.initialize returns Errors - renamed savePayload to workerMsg for a more general name - added a new validateRcptChan channel - savedNotify renamed to notifyMe for more fluent code readability - backend timeout now a constant ProcessTimeout - new ValidateRcpt method implimented to add validateRcptChan channel - getNumberOfWorkers() renamed to workersSize() - saveMailWorker() renamed to workDispatcher() so the name better reflects what it does - Change the Processor interface to add a new task param, allows the selecting of what task to do (so far, save or validate) - Update all processors to use new Processor interface - Renamed Envelope.Info to Envelope.Values - New Canned.FailRcptCmd response message for when recipient does not exist - Added PushRcpt and PopRcpt to Envelope
…make sense. *email.Envelope reads better - renamed saveMailChan to conveyor to be more concise - merged validateRcptChan to conveyor - simplified - ProcessorLine renamed ProcessorStack to better describe structure - Default processor now a constant, used when no processor set in config - Renamed Shutdown and Initialize types used for helping to pass closures that meet Shutdowner/Initializer interfaces, improves readability - config extractor now supports omitempty json struct tag - server now checks RCPTO using backend gateway - rename RemoteAddress to RemoteIP for clarity (form a module point of view, it now looks like mail.Address{} instead of envelope.EmailAddress{}) - updated the sample config - backend_name removed from config
- test mysql connection & access to table - guerrilla-redis-db processor bug fix
- rename constants for the mysql processor - update readme
- remove name from nackends.New - Update readme to reflect code
…different processing stack for validating. Better efficiency and ability to control
- update glide - add envelope.go tests
- make test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
api.go
Outdated
"time" | ||
) | ||
|
||
type Daemon struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could add a comment here about how Daemon
differs from the Guerrilla struct
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
api.go
Outdated
return errors.New("d.Config nil") | ||
} | ||
var oldConfig AppConfig | ||
oldConfig = *d.Config |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can merge lines 130-131
api.go
Outdated
if err == nil { | ||
l.SetLevel("info") | ||
} | ||
return l |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should probably do some error checking or return an error. Looks like if an error is returned on line 174 this will return nil and caller will panic. Although this is probably used to frequently for error checking on the caller to be reasonable. Maybe cache a log in the daemon/guerrilla struct when logs are rotated/changed and get that directly afterward. Error check on getting log when rotating, afterward isn't required.
backends/gateway.go
Outdated
return NewResult(response.Canned.FailBackendNotRunning + gw.State.String()) | ||
} | ||
// place on the channel so that one of the save mail workers can pick it up | ||
savedNotify := make(chan *notifyMsg) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Considering how frequently we're calling Process
and ValidateRcpt
, these notifyMsg
channels might be a good candidate for pooling
sc.Hostname = h | ||
sc.MaxClients = 100 | ||
sc.Timeout = 30 | ||
sc.MaxSize = 10 << 20 // 10 Mebibytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: Megabytes
c.Servers[i].Timeout = 20 | ||
} | ||
if c.Servers[i].MaxSize == 0 { | ||
c.Servers[i].MaxSize = 10 << 20 // 10 Mebibytes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: megabytes
guerrilla.go
Outdated
} | ||
return nil | ||
} | ||
|
||
func (g *guerrilla) Shutdown() { | ||
|
||
// shot down the servers first |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: shut down
mail/envelope.go
Outdated
"time" | ||
) | ||
|
||
const maxHeaderChunk = iota + (3 << 10) // 3KB |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why use iota here instead of just 1?
server.go
Outdated
@@ -136,6 +137,19 @@ func (s *server) configureLog() { | |||
} | |||
} | |||
|
|||
// setBackend Sets the backend to use for processing email envelopes |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sets
Thanks @jordanschalm for the review - will be going through these today. |
@jordanschalm still going through it (and fixing problems), marking the ones that are fixed. Just want to say thanks again. Your reviews are very thorough with lots of attention to detail! Will have the new README ready for review soon too. |
Worked on adding the pooling of notifyMsg chans. Now working on another optimization: In |
…tors configured - fix issues found during code review on PR #71 - fix bug with server ignoring the -v flag - default config now named as 'goguerrilla.conf.json' for syntax highlighting - changed api so AppConfig is passed by value, so the caller can't modify it / prevent using it as global state value - Safeguard api functions from calling out of order (check for nil) - removed CmdConfig
@jordanschalm Here is the new README ready for review - https://github.com/flashmob/go-guerrilla/blob/more-backends-refactoring/README.md - things to check: typos, grammar & flow. Also feedback on if it's using the right words to describe things. Thanks! |
- fix race condition with the client pool
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me. The README was getting pretty long, and I think this makes it a lot easier to get into. Ordering of topics is good. Intro->Features->Standalone->Package->Backend/Processors. Maybe could move the Starting/Usage
and Using NGINX as a Proxy
to where you first introduce the daemon in Getting Started
as subsections or relegate them to the wiki. Besides that noticed a couple of typos.
README.md
Outdated
==================== | ||
|
||
An minimalist SMTP server written in Go, made for receiving large volumes of mail. | ||
An lightweight & modern SMTP server written in Go, made for receiving large volumes of mail. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A lightweight
README.md
Outdated
### What is Go Guerrilla SMTPd? | ||
### What is Go-Guerrilla? | ||
|
||
It's an SMTP written in Go, for the purpose of receiving large volume of email. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
an SMTP server
README.md
Outdated
add_header Auth-Server 127.0.0.1; | ||
add_header Auth-Port 2525; | ||
} | ||
The main job of a go-guerrilla backend is to validate recipients and deliver emails. The term |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depending on how pedantic you want to be, could standardize the capitalization of "Go-Guerrilla". The README has Go-guerrilla, Go-Guerrilla, and go-guerrilla ;-)
README.md
Outdated
### What is Go Guerrilla SMTPd? | ||
### What is Go-Guerrilla? | ||
|
||
It's an SMTP written in Go, for the purpose of receiving large volume of email. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"receiving large volumes" or "receiving a large volume"
…patcher can be re-entered
@dvcrn @peterkrejci @mrcpvn @eliezedeck |
@flashmob amazing 😄 fantastic job! |
Edit: deleted comment as no longer relevant! See new comment