The Batch Processor is a headless client that starts automatically when the server starts and runs without any direct user interaction. It is typically used for backend automation and maintenance tasks. Since this client is initiated as part of the server’s lifecycle, it is ideal for tasks that need to execute consistently on startup or at regular intervals.
The Batch Processor can be configured with specific credentials or startup arguments, depending on your needs, and it can either run a one-time task (like server maintenance) or be scheduled to run recurrently using the Scheduler Plugin.
You can find more detailed information about Batch Processors here.
Features
No User Interaction*: The Batch Processor runs automatically with no need for a logged-in user interface.
Login Credentials: You can configure a user credential for authentication, managed through the Servoy Admin Page.
Startup Arguments: Startup arguments can also be set, making it easier to customize the batch session’s behavior during initialization.
Scheduling: You can bind the processor to a startup method for execution upon server start, also schedule recurring tasks via the Scheduler Plugin.
Examples
Bind to a startup method
A simple method that runs when the server starts. It can be configured to perform any server-side tasks, like cleaning up logs or running diagnostics In this example, the Batch Processor will clean up old logs and session data in the performMaintenance() function.
/** * Callback method for when solution is opened. * * @param{String} arg startup argument part of the deeplink url with which the Client was started * @param{Object<Array<String>|String>} queryParams all query parameters of the deeplink url with which the Client was started, key>string if there was one value else key>Array<String> * * @properties={typeid:24,uuid:"E4E0B0D5-B12B-40B1-8E4B-CC5670C9C5D2"} */functiononSolutionOpen(arg, queryParams) {// Example: Initializing system-wide settingsapplication.output('Batch Processor: Server has started. Initializing system...');// Perform any server-side maintenance or setupperformMaintenance();}functionperformMaintenance() {// Maintenance logic// You could perform database cleanups, data synchronization, etc.application.output('Batch Processor: Starting maintenance tasks...');// 1. Clean up old server logs (keeping only the last 3 months)var cutoffDate =newDate();cutoffDate.setMonth(cutoffDate.getMonth() -3); // Logs older than 3 monthsvar logQuery =databaseManager.createSelect('db:/example_db/log_table');logQuery.where.add(logQuery.columns.log_date.lt(cutoffDate));// Delete old log entriesvar deletedLogs =databaseManager.getFoundSet(logQuery).deleteAllRecords();application.output('Batch Processor: '+ deletedLogs +' old log records deleted.');// 2. Remove outdated session data (keeping only the last 7 days)var sessionCutoffDate =newDate();sessionCutoffDate.setDate(sessionCutoffDate.getDate() -7); // Sessions older than 7 daysvar sessionQuery =databaseManager.createSelect('db:/example_db/session_table');sessionQuery.where.add(sessionQuery.columns.session_date.lt(sessionCutoffDate));// Delete old session entriesvar deletedSessions =databaseManager.getFoundSet(sessionQuery).deleteAllRecords();application.output('Batch Processor: '+ deletedSessions +' old session records deleted.');application.output('Batch Processor: Maintenance tasks completed.');}
Run once and shutdown
Sometimes, the processor only needs to perform a task once, such as server initialization or cleanup, and then stop.
/** * Callback method for when solution is opened. * * @param{String} arg startup argument part of the deeplink url with which the Client was started * @param{Object<Array<String>|String>} queryParams all query parameters of the deeplink url with which the Client was started, key>string if there was one value else key>Array<String> * * @properties={typeid:24,uuid:"E4E0B0D5-B12B-40B1-8E4B-CC5670C9C5D2"} */functiononSolutionOpen(arg, queryParams) {runOneTimeTask()}// Run a one-time task on server startup and then shut downfunctionrunOneTimeTask() {application.output('Batch Processor: Running one-time task...');// Example: Processing data or initializing resourcesprocessData();// Shut down the batch processor after the task is doneapplication.output('Batch Processor: Task completed. Shutting down.');application.exit(); // This will shut down the batch processor}// Example method for processing datafunctionprocessData() {application.output('Batch Processor: Starting data processing task...');// Insert data processing logic here // 1. Use QB select to retrieve pending ordersvar orderQuery =databaseManager.createSelect('db:/example_db/orders');orderQuery.where.add(orderQuery.columns.status.eq('PENDING'));var orderFoundSet =databaseManager.getFoundSet(orderQuery);// 2. Loop through the foundset and process each orderfor (var i =1; i <=orderFoundSet.getSize(); i++) {var record =orderFoundSet.getRecord(i);// Example processing logic: Update the status of the orderif (record.status ==='PENDING') {record.status ='PROCESSED'; // Mark order as processedif (databaseManager.saveData(record)) {application.output('Batch Processor: Order ID '+record.id +' marked as PROCESSED.'); } else {application.output('Batch Processor: Failed to update Order ID '+record.id +'.'); } } }application.output('Batch Processor: Data processing task completed.');}
In this scenario:
The Batch Processor runs the runOneTimeTask() method.
Once the task completes, the application.exit() method is called, which shuts down the batch processor.
This is ideal for one-time tasks that don’t need to keep running after startup, such as initializing services or processing data at the server boot.
Schedule a recurring task
To run a task at recurring intervals, the Scheduler Plugin can be used. Here’s how to schedule a task that runs every 10 minutes:
/** * Callback method for when solution is opened. * * @param{String} arg startup argument part of the deeplink url with which the Client was started * @param{Object<Array<String>|String>} queryParams all query parameters of the deeplink url with which the Client was started, key>string if there was one value else key>Array<String> * * @properties={typeid:24,uuid:"E4E0B0D5-B12B-40B1-8E4B-CC5670C9C5D2"} */functiononSolutionOpen(arg, queryParams) {// Scheduling a recurring task using the Scheduler Pluginvar jobName ='recurringTaskJob';plugins.scheduler.addCronJob(jobName,'0 0/10 * * * ?', recurringTask); // Schedule a task to run every 10 minutes}// Define the recurring taskfunctionrecurringTask() {application.output('Running recurring task...');// Insert the task logic here (e.g., data sync, report generation)syncData();}// Example data synchronization taskfunctionsyncData() {// Logic to sync data goes hereapplication.output('Batch Processor: Starting data synchronization task...');// 1. Use QB select to retrieve unsynced sales datavar salesQuery =databaseManager.createSelect('db:/example_db/sales');salesQuery.where.add(salesQuery.columns.synced.eq(0)); // 0 for unsynced recordsvar salesFoundSet =databaseManager.getFoundSet(salesQuery);// 2. Loop through the sales records and send data to the external systemfor (var i =1; i <=salesFoundSet.getSize(); i++) {var saleRecord =salesFoundSet.getRecord(i);// Send data to the external system (assuming an API endpoint)var response =scopes.globals.sendDataToExternalSys('https://external-system.com/api/sales', { id:saleRecord.id, amount:saleRecord.sale_amount });// 3. If successful, update the record as syncedif (response &&response.statusCode ===200) {saleRecord.synced =1; // Mark the record as syncedif (databaseManager.saveData(saleRecord)) {application.output('Batch Processor: Sale ID '+saleRecord.id +' successfully synced.'); } else {application.output('Batch Processor: Failed to update Sale ID '+saleRecord.id +' after sync.'); } } else {application.output('Batch Processor: Failed to sync Sale ID '+saleRecord.id +'. Response: '+response.statusText); } }application.output('Batch Processor: Data synchronization task completed.');}
Key Points:
Scheduler Plugin is used in onSolutionOpen to add a CRON job that runs every 10 minutes.
The CRON expression '0 0/10 * * * ?' schedules the task to execute at the start of every 10-minute period.
The recurringTask() method contains the logic that will be executed every time the job runs.
This setup is useful for tasks like recurring data synchronization, sending automated emails, or running periodic checks.