We’re excited to introduce a new blog series, covering all things XAP, including insider tips and tricks from our team of architects and developers working around the clock to make XAP work for you. The GigaSpaces blog has evolved substantially, and our goal is to ensure you are kept in the loop with product updates, in-depth tutorials, and how-tos in order to help you up your professional game and offer real value to your team. In 2017, the blog will grow to provide even more content, so be sure to check back regularly as we have heaps of new information on the way. This is the fourth post in the series.
Tutorial: Dynamically Executing New Tasks Based on Real-time Updates with XAP Class-Loader
Reloading tasks with a different implementation to any system in runtime is never a simple or easy job.
The alternatives available are usually restarting the whole server, overriding the older implementation with a newer one with the same name, or preloading tasks in advance. But are these really the only solutions?
None of the alternatives above feel like the optimal solution. Restarting the server usually takes a lot of time—not to mention downtime may not even be a possibility, as downtime equals money and most mission critical systems are 99.999 percent uptime compliant.
Reloading the same task forces us to rename the task over and over since you can only load one task due to the unique name constraint. This alternative overcomplicates the process, making it hard for everyone to actually manage the tasks. Furthermore, renaming each task can create a lot of confusion between the different teams, developers, and QA departments. If we can recall our essay assignments back in the day, we’ve probably all used the versioning methodology of “Final_Version,” “Final_Version_1,” “Final_Version_1.1,” etc.
As if it wasn’t confusing enough back then, we certainly don’t need to keep doing it nowadays at our enterprise projects as well!
The third alternative is to load your tasks in advance. However, in order to do this, one would have to think about the task logic needed to execute in advance, long before it’s actually needed or even implemented. Not only is this a challenging task, but also, it might be an impossible one nevertheless as we will see in the example below.
From this point onwards, I will introduce an advanced solution to help you reload modified tasks.
Reloading the Same Task: An eCommerce Example
If you are used to working with JVM based servers, you’ve probably encountered this issue of having to run the same task but with different logic. So when you first try to execute the task the server loads it, but when you try to reload the task again with a different implementation, you’re actually running the same old task again.
Since the JVM loads a specific class only once, caches it, and then for the rest of the time it uses the same loaded class (as a class cannot be unloaded from the JVM), this means that you won’t be able to load the same task with the new implementation.
For example, let’s take a big eCommerce company that has a lot of trade data. They frequently execute a task that sums all the transactions from Asia to the United States, adding in the tax which was for those transactions. When the tax rate is updated, as it usually does over time, the task should also be updated. But how?
Class-Loaders to the Rescue
In order to understand how to best solve this issue, let’s get back to the basics. In the developer world, a task is a user-defined business logic which is executed on the server side asynchronously. In the XAP world, we refer to this as a “Space Task.” This means users can execute some of their business logic (like clean the server, update entries is the space, etc.) without the need to wait for the execution to end (asynchronously).
Having worked on XAP for a while now, I can safely say that our solution takes into consideration the issues mentioned above. While classes can’t be unloaded from the JVM, it is possible to load the same class from different class-loader. JVM defines class as a pair of [class-loader, class-name], e.g. the class-loader that the class has been loaded from, and the name of the loaded class. Therefore, our solution is based on the fact that we can load the same class from a different class-loader, meaning we can load the same task with new business logic.
In XAP 12.1, we’ve added the ability to create a new class-loader every time the user wants to load the new implementation of the same task, which allows the user to create multiple versions of the same task. No more renaming!
With this approach, we now have the ability to load as many versions of a class as we’d like, because each class can be loaded from a different class-loader.
From the user’s perspective, in order to load a task from a different class-loader, you only need to annotate the class with the @SupportCodeChange(id=“…”) annotation.
The String id gives you the ability to control from which class-loader the task will be loaded. And if you decide to update your task, you’ll simply need to update the id and the task will load from the specific class-loader.
By providing you with more agility, you have the ability to dynamically execute new tasks based on real-time updates, not your personal predictions or assessments beforehand. And best of all, the renaming process is no longer necessary.
We don’t expect you to know what the tax rate will be next week or next year, but now you have the ability to run tasks with the current tax rate, even when it changes. With our solution, you’ll be able to manage your tasks with ease and without any downtime to your system.