Use the database to save the status of the executions, it will serve not only to show the user what is happening, but also the execution history.
Create a Table (something like ProcessStatusException ) where you can have a Description field and another Status (I always have an ID field that is primary key with autoincrement, makes control very objective and easy to know which record I'm working on.)
The description field can be text to describe the routine that was executed and the status field controls whether it was executed or not and whether it succeeded.
In service, change the method that you run daily (in our example, let's call itBackupRoutine) for each step of the Method to perform status update in the database.
Example:
void RotinaDiariaBackup()
{
try
{
rep.InsereStatusProcessoIniciado();
this.ExecutaBackup(); //este metodo é a sua rotina (aquilo que o serviço ja executa de tempos em tempos.
rep.InsereStatusProcessoExecutadoSucesso();
}
catch(Exception)
{
rep.InsereStatusProcessoExecucaoFalha();
}
}
Of course, there are some flaws in this method, from several points of view so keep in mind the design of the solution, not this code itself.
You should better consider error handling, consider that the methods you enter in the database may also fail (you should have an alternate error log for crawling - a txt or windows log).
But in general, let's explain the logic:
rep = repository for access to the database that saves the process data, for simplicity, I did not create a processExecution object, but, it is highly recommended because you may need to represent more than status and description.
Then, the methods would receive an instance of ProcessExecution (which does not yet exist) to perform the actions.
rep.InsereStatusProcessoInitiado (); = Basically this excerpt inserts into the database a row in the ProcessExecutionStatus table with the description you want by default and status (say status = 0 is execution in progress).
rep.InsereStatusProcessOnSuccess (); = Make an update on the line you entered now by updating the status of the table for success (say it is Status = 1).
If one of the previous methods fails, an exception will be thrown and you update the status record to 2 (status with error).
rep.InsereStatusProcessOfFailure ();
Well, you should pay attention to the fact that other methods may fail that are not your routine (successful update may fail), so you should think about how to control this flow (transaction?)
Once the service modifications are finished, implement a screen that shows the records of the ProcessProcessStatus table and you will have the status of what was executed and also what is being executed, since the screen only shows the records.
This control table approach is quite common, however, there are some problems:
-
The status of the table is not the status of the service, so if the service fails for some reason other than the routine, the screen does not show this.
-
The screen shows a photo in the time it was inserted, there is no communication between the processes, so it does not show the status of the service at that moment, it shows the last change of record that was possible, if you you want to use the screen to monitor the service, it is not that way, you will have to implement another form of access to the service itself (which is usually a bit more complex).
-
Database performance, your service currently has no connection to the database, making fewer requests and as a result, the bank (which can be a simple machine) does not suffer from this, you will be going to (both to read to the screen and to execute their routines).
-
Please do not make a Select * from ProcessExecutionStatus on the screen, put a conditional or a top, over time the table will grow. This is solved by itself that you correctly implement the repository and access the screen of the same classes treating the service as if it were a GUI, but not everyone thinks so, many have no layers or treat as another mini-system.
Finally, if you need to include new routines in this system, just put a RowType column in the table and create a new Method for the new routine, following the same structure and the screen will already reflect the new statuses, it is easy to give maintenance and expand, something like this:
void RotinaDiariaEmails()
{
try
{
int tipoRotina = 1; // 1 = envio diario de emails - 0 = backup
rep.InsereStatusProcessoIniciado(tipoRotina);
this.ExecutaEnvioEMails(); //este metodo é a sua rotina
rep.InsereStatusProcessoExecutadoSucesso(tipoRotina);
}
catch(Exception)
{
rep.InsereStatusProcessoExecucaoFalha(tipoRotina);
}
}
In the service, you would call the methods in sequence or have another queue structure that executes the methods:
void StartSomeTimes()
{
RotinaDiariaEmails();
RotinaDiariaBackup();
}
You probably have a timer in your service that runs from time to time, you would call StartSomeTimes in the body of the method that the timer executes.