Chronicle Microservices - question on blog post

90 views
Skip to first unread message

Ben

unread,
Oct 18, 2016, 8:52:27 AM10/18/16
to Chronicle
I have a question on a Vanilla java blog post Peter wrote a few months ago on using Chronicle Queue + Wire to implement micro services.  I would ask my question on the blog, but for some reason the ability to leave comments via Disquss is broken for me.

I like the idea of making services pluggable via listener approach as outlined in part 2 of the series, but was wondering what techniques people used to manage separate services being dependent on a set of listener interfaces.

Do people accept some services have compile time dependencies on other services, or do the interfaces get moved into a set of very thin "interface" libraries that services can choose to depend on ?  I guess using OSGI you could limit the dependencies to just these publicly available interfaces, but you still have at least some form of dependency between services at this point.


Thanks,

Ben

Peter Lawrey

unread,
Oct 18, 2016, 10:57:44 AM10/18/16
to java-ch...@googlegroups.com
How much they depend on one another is up to you.

You could have the microservices using the same code base (possibly different versions of it)

You can have a shared API library they both depend on, but the rest of the code is in different modules.  This is my preferred approach. Even if the versions used are inconsistent, this doesn't have to be a problem (see below)

You can have different copies of the interface provided they are compatible enough. 

For example;
- the method(s) you use have to have the same name (you can have a change of method name but this isn't supported)
- method(s) you don't use can be completely different or absent.
- if the method arguments have an assumed type (ie the type is omitted) only the mandatory field names of your data transfer objects need to match. Optional fields can be added or dropped.
- some types can be automatically converted and don't need to match.
- the package for a class and even it's name doesn't have to match (provided you have given a mapping)

Regards,
   Peter.

--
You received this message because you are subscribed to the Google Groups "Chronicle" group.
To unsubscribe from this group and stop receiving emails from it, send an email to java-chronicle+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Ben

unread,
Oct 19, 2016, 4:11:42 AM10/19/16
to Chronicle
Hi Peter - thanks for the reply.  I agree a “thin” shared and versioned library is a good way to go.

It’s good that Wire’s support for optional fields means you could upgrade a version of the API from a publishing service without needing to upgrade the consumer when running over a transport.  I've debugged most of the code and even implemented some basic marshallableIn/Outs for HTTP and Vertx event bus over the past week.

What I am curious about is the approach you take when an interface/DTO changes and you then want to debug two services without a transport as outlined in the blog post.  e.g. if an upgraded interface definition contained a new method argument or a new method then you can no longer inject the current consumer (v0.1 of API) into an upgraded publisher (v0.2 of API) in a single JVM without compilation errors.  The only way I can see you would do this is by introducing a new version of the interface and DTO, and then either:

  1. Creating a wrapper so that calls on the injected delegate are downgraded from new API calls into old API calls.
  2. Enhancing the publishing service to support injection of the old interface and sending old API calls.

Option 2 has the added advantage of being useful when running across a transport and publisher only discovers consumers who implement the old API version.

Thanks,

Ben
To unsubscribe from this group and stop receiving emails from it, send an email to java-chronicl...@googlegroups.com.

Peter Lawrey

unread,
Oct 19, 2016, 5:49:12 AM10/19/16
to java-ch...@googlegroups.com
Hello Ben,
   When updating a method in a manner which is not backwardly compatible, I suggest deprecating the old version so it can be still called in tests (and producers which have not upgraded), but encouraging the producer to migrate to the newer method ASAP.  You might have to version the method with a counter

@Deprecated
default void method(DTO dto) {
    method2(new DTO2(dto));
}

void method2(DTO2 dto2);

By having both version, you can still replay older logs and test your code with production data.  Once you have some production data with the new message types and no one is using the old version you can retire them.

BTW If you have support for HTTP and Vert.x I would be interested in opening a project so we can support/extend it in the future. we have a project for Jetty/ebsockets

Regards,
   Peter.

To unsubscribe from this group and stop receiving emails from it, send an email to java-chronicle+unsubscribe@googlegroups.com.

Ben

unread,
Oct 20, 2016, 8:41:30 AM10/20/16
to Chronicle
This works nicely :-)  Thanks for the tip.

I will PM you re the vertx/http.
Reply all
Reply to author
Forward
0 new messages