Hi everybody. As part of GOSSIP-79 I've been noodling how to modularize the code. I have a few ideas I'd like to bounce around on the list. I'm not strongly bound to any of these, and realize nothing is perfect. Please make suggestions!
My end goals are to 1) remove the UDP requirement, 2) make it simple for an embedder to replace (marshaling, transport, etc.) with custom implementations. Here's a gist in case HTML munging from my copy-paste into this email messes format up. https://gist.github.com/gdusbabek/12213609e7b70b8678bfad28412d1834 *Sending* The configuration would drive what kinds of transports are going to be supported (e.g.: UDP, HTTP, Pure TCP, etc.). At startup, a factory would be created for each transport type. An easy approach would be to define a factory interface and expect all implementations to support a common constructor. The factories would then be added to some service directory or context object. The factories would create/return client instances. When it’s time to send, the approach would be something like: service discovery v client factory v v client impl v v v context.getSender(uri).send(payload), or context.getSendFactory(uri.getScheme()).send(uri, payload) changes needed: 1. Factory interface 2. Factory implementation (start with UDP) 3. Client interface 4. Client implementation (start with UDP) We can add new implementations after that. The interfaces will need to be robust enough to opaquely allow things like socket reuse. It’s why I think it is important to separate the factory interface from the client interface. *Receiving* The configuration would specify which listener is going to be used. That would then drive the class that gets instantiated. The main job of the implementations would be to receive messages and pass them on to an instance of GossipCore (the next layer). The implementations would opaquely handle details related to thread pools, etc. We need to decide whether or not to support running multiple transports (e.g.: UDP, HTTP, etc.) concurrently. There is no technical reason that multiple transports cannot run at the same time. However, since transport is an explicit field of the gossip message, it makes sense to run a single transport in a homogeneous cluster. I’m trying to come up with a good reason where, say HTTP and UDP make sense at the same time, but I cannot come up with anything so it may not be a good idea. “Testing” is the only good reason I can come up with. *Layers* We would need to give some thinking to the service interfaces and boundaries of the jobs of GossipCore, GossipManager, PassiveGossipThread and ActiveGossiper. This will allow for better testing and a high degree of customization via switching interface implementations of various components. The latter will make it easier for other projects to consume Apache Gossip and even customize it. It may make sense to let threading be handled by the layer implementations rather than base classes. My reasoning is that different transports have different concurrency requirements. *Protocols* Protocols are about how the messages are marshaled (e.g.: JSON, xml, binary). Right now this is tightly coupled to JSON/Jackson. From an embedded library pov, it may not be the best dependency to have. Same goes for Gson, though it is not a dependency. No ideas on how to deal with this other than factories and reflection. I think what I’d like to see is a BYO approach to JSON. Maybe tackle this later. *Encryption* I’m not sure if encryption fits in at the protocol or at the transport layer. I can see it both ways. From an implementation standpoint, I think it fits as part of the transport layer (e.g.: HTTP vs HTTPS). That's all! Cheers, Gary.
