API App Messaging (Part 2)

The first part of this article showed an example of asynchronous API App Messaging (Part 1)

In the second part of the series I will show how you can implement synchronous messaging with an example.

The Cache

For this example I will add a new search data caching module. A MySQL database will be installed in order to store the cache. The updated microservices configuration is as follows.

Microservices Async Messaging

The API endpoint and the two search modules call functions in the Cache module synchronously. The cache module will have functions to add and get cached search results stored in the MySQL database.

The Database

API Query Cache

A simple 2 table schema stores the keywords and the results. This schema is automatically generated by the .NET Entity Framework using the model classes.

The Remote Procedure Call (RPC) Client and Server

Remote Procedure Calls enable one process to call a function in another process as if its a local one. The calling thread blocks or waits until results are available from an external module - in this case the Cache module. The underlying queuing mechanism is used to perform the RPC.

The RPC client and server require the following code to setup and configure. The code below initializes the RPC client.

The code above is from the controller class constructor. The API endpoint queries the cache from here. Each Gitbub and Bitbucket modules also declare RPC endpoints to create cache entries.

At the other end of the RPC channel is the module that manage the cache. It is initialized as follows.

The .NET API provides a timeout mechanism in case there are long delays due to issues with communications.

The API APP Endpoint

The the RPC call will time-out if there is an unacceptable delay in responding. This ensures the function does not block forever in case of a communications failure. The default 5 second timeout can be changed in the CreateRPCEndpoint function call.

In addition, a callback function can be supplied to get a notification back when a timeout or a disconnect occur.

Step 1. Search the Cache : Search the cache if the search results are available in the cache. See GetCachedResultsfunction description below for details.

Step 2. Dispatch search jobs : The query is sent to each service component via the queue if the results aren’t available in the cache. The correlation Id of each query request is recorded so that the returned data can be matched to the initial query.

Step 3. Do other work : Do other work while the queries are performed.

Step 3. Collect the search results : The results of the query are available on the return queue. Pick up the results and return it to the client.

The GetCachedResults Remote Procedure Call

The following functions gets executed when the GetCachedResults is called. The callee is the actual procedure in the cache module.

The Search Modules

Here is how the Bitbucket search module create cache entries.

Step 1. Call the external API : The SearchAsync functions calls a Bitbucket API to search on the keyword.

Step 2. Save results in the cache : Then it calls the CacheResult RPC function to save the results in the database.

Conclusion

There are times when its a good idea to bundle all commonly shared code in a microservice. It makes things easy in an administrative sense.

Although the biggest advantage comes from the ability to have a shared module consuming the system resources only once ala Singleton. In these circumstances blocking RPC calls as demonstrated here will become handy.

This concludes the synchronous sample. The sample code is available as usual on Github.

I welcome any comments or other feedback.

Further Information