The Power of Background Services in Software Development
You may have wondered how a program can send reminders to users on a weekly basis or process a file that was attached to an email without a user ever reading the message. Or how software applications can monitor their health or initiate automated health checks? All these problems have one thing in common – something behind the scenes expects these events or is on pins and needles for its time to come and do the job. These are the so-called background services or sometimes you may encounter them as workers.
In this article, you will understand some key aspects of how these applications work, how they can be maintained, and get a practical example and benefits of their usage.
Understanding background services
It goes without saying that most people are used to applications that respond almost immediately to clicks. Furthermore, they may even stop using a program if it’s too slow. However, in a lot of cases, a background service actually executes a lot of the operations behind the scenes in order for the user to be satisfied and their experience not to be interrupted. Moreover, the workers run separately from the main application which loses the coupling and avoids the crash of the main application in case a worker goes down. Not to mention the fact that in this architecture, units can be deployed individually and scaled apart from each other.
There are different configurations and types of background services. А good enough generalization is to divide them into ones that respond to events and ones that run on schedule.
The event-driven architecture usually uses queues and publish-subscribe design patterns. These paradigms are so widely used that the biggest cloud providers, namely Microsoft and Amazon with which we tightly work, have many articles regarding them.
Background jobs that are executed on schedule can be set up diversely with the help of cron command-line utility syntax which gives a bunch of options for configuring the recurrence.
Case study: using background services for a fintech client
You may get a better understanding of the value of background services if you dive into the problem for which we used them. A client in the fintech industry approached us with the need to automate a tedious human-driven process. The operation was bound to errors and consumed the valuable time of employees. In short, a large number of documents had to be transferred monthly from an on-premise database to a SharePoint library by following specific rules for the folder structure. At first sight, it is a relatively simple job, but the volume of the work is what makes the process stand out as a disadvantageous one. As you can already feel from the descriptions of the request and the background services, the requirements fit quite well with what the workers are proficient at. Furthermore, the client insisted on the solution being on-premises since all components in the architecture are on their own servers. However, there are intricate details that must be thoroughly considered to have a smooth process.
Hardware resources
There is a strong tie between the resources a job consumes, how often, and at what time it is executed. In our case, the process was quite heavy in terms of the data that had to be transferred. Although it was alluring for the client to get the documents uploaded as soon as possible, it turned out that scheduling the job for some time during the night, when the server was not in use for other processes, was way more beneficial. In that way, the machine could serve its purpose during the day without any downtimes due to the increased load from the job but also be utilized during a period of decreased load.
The balance between frequency and the resources used should also be taken into account. For example, there might be underlying problems with the scheduling, or running the job too often can use more resources without actually increasing productivity simply because there might not be enough work. In our case, for instance, documents were not uploaded to the database every minute, so running a job that processes no new files was pointless. In the other extreme case, if a job is run too rarely, it might take a lot of time and resources once it is resumed.
Monitoring
One downside of the background services lies in their name – background. Naturally, since they are console applications, they come without a beautiful front-end page where you can view, and manage your jobs, view logs, etc. However, most modern libraries that help in the implementation of such workers, provide a simple web management page for these tasks out of the box.
It goes without saying that errors happen for one reason or another. Thus, the people responsible for the process, should monitor the jobs on the management page and take action when something goes wrong. Furthermore, such libraries make users’ lives easier by allowing them to view all past and present runs of the jobs. One can also schedule them with the help of an intuitive interface and provide health-check information about the programs executing the tasks.
Asynchrony
Hardly is there any doubt that the asynchronous nature of the jobs is another pitfall that awaits. It is of high importance to make sure that a job does not run more than once simultaneously. Imagine in our case that two separate workers execute the same job.
This means that they would both fetch some data from the database and would both send this data to SharePoint which is unwanted behavior. Even if you do some additional checks, a lot of race conditions might appear that are not worth the hassle. On top of that, in case there is a long-running task, one should consider safe exit paths in case of a failure. For example, some libraries provide the option of implementing handlers in case the service stops abruptly.
A point of high importance is to ensure reentrant jobs. For instance, let’s say you have a program that sends emails to a list of people. In case an error appears while the program is in the middle of the list, you wouldn’t want to execute again the same job and send emails twice to some of the recipients. If we translate this scenario to our case, we have to double-check if a document hasn’t been already uploaded to SharePoint by a previous run.
Conclusion
In conclusion, background workers can be the best friends of a developer in order to resolve some complex tasks. Although they may be simple at first sight, there are some intricate details that must be taken into account when integrating them into your architecture.
If you have any questions regarding the usage of background services in your project or their benefits, please don’t hesitate to reach out!