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.
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.
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.
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.
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.