Skip to content
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

Create abstraction for SMTP queue storage #262

Open
foxcpp opened this issue Aug 8, 2020 · 4 comments
Open

Create abstraction for SMTP queue storage #262

foxcpp opened this issue Aug 8, 2020 · 4 comments
Labels
mta-out Related to MSA or outgoing message processing part of MTA functionality. rfc Request For Comments (ongoing discussion / research needed).

Comments

@foxcpp
Copy link
Owner

foxcpp commented Aug 8, 2020

That would enable writing alternative queue storage implementations. Discussion needed to figure out if there is need and what considerations are.

@foxcpp foxcpp added mta-out Related to MSA or outgoing message processing part of MTA functionality. rfc Request For Comments (ongoing discussion / research needed). labels Aug 8, 2020
@joe-getcouragenow
Copy link

It would be great is the storage can be integrated into the golang code and for it to be HA.
So for a basic user that just need to start the binary on 1 or 3 servers and the whole thing stays in sync and does leader elections etc automagically.

This does it.
https://github.com/lni/dragonboat

And many devs use it to make KV stores in golang to be HA. So it is mature.
Some examples are: https://github.com/search?q=lni%2Fdragonboat%2Fv3&type=Code

@foxcpp
Copy link
Owner Author

foxcpp commented Aug 27, 2020

Things to be abstracted out from queue code are:

  1. Scheduler

Determines when message delivery should be attempted. Interface is roughly this:

Schedule(time time.Time, attemptId string)
Wait() (attemptId string)

This part is already mostly separated - in current implementation that's TimeWheel struct (funny name, should have named it TimerBucket or something :) ).

Such scheduler should be able to preserve information across server restarts and so on. In current implementation queue timers
are recreated from meta-data stored in a filesystem directory.

  1. Meta-data & message store.

Message queue needs to keep 3 pieces of data: Meta-data (serialized module.MsgMetaData structure), message header and message body.

This part of queue code is hard-wired with the rest of queue logic so some refactoring is required here.
I would define the interface like this:

StoreMessage(attemptId string, metadata QueueMeta, hdr textproto.Header, body io.Reader)
LoadMetadata(attemptId string) QueueMeta
LoadHeader(attemptId string) textproto.Header
LoadBody(attemptId string) io.Reader

Can take a step forward and use a dumb key-value store interface and let queue itself handle necessary serialization
(like imapsql module has abstracted message contents storage).
Note it is important for such storage to support large blobs and streaming, potentially with local cache since body may be read several times on delivery.

@foxcpp
Copy link
Owner Author

foxcpp commented Aug 27, 2020

It would be great is the storage can be integrated into the golang code and for it to be HA.

Frankly, I am not familiar with consensus protocols like Raft. So I was hoping for feedback on what kind of interface would be appropriate between queue code and storage. I wrote a detailed description above.

@pcmid
Copy link

pcmid commented Aug 27, 2023

I have an idea to achieve this using NATS Jetstream.
By importing github.com/nats-io/nats-server/v2/server, it can be built into golang code to implement a distributed message queue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
mta-out Related to MSA or outgoing message processing part of MTA functionality. rfc Request For Comments (ongoing discussion / research needed).
Projects
None yet
Development

No branches or pull requests

3 participants