I need to implement the following requirement for my job.
- When a user starts a new application, a 5-minute timer begins.
- If the user makes any edits to the application before the 5 minutes is up, the timer is canceled.
- If the timer runs to completion, an email is sent to our company ("an application was created but abandoned").
The web server for this project is a .NET MVC project, though other than the Home Controller, all controllers inherit from System.Web.Http.ApiController rather than System.Web.Mvc.Controller. The front end is Angular 6.
It seems easy enough to start a 5-minute timer that will execute the "email send" method after 5 minutes. I'm stuck on how to implement the ability to cancel the timer if the user edits the application before the timer has run out. The command to start the application and any subsequent edits will come as separate queries to the API, so I don't have any state maintained from call to call.
My current idea is to create the timer via System.Timers.Timer when the application is started and store the timer in an ObjectCache under a unique ID representing that particular application. Then when the edit action is called, I can check the cache to see if a timer is stored that matches the application being edited, and if so, cancel the timer. If such a call doesn't come within 5 minutes, the timer will fire and the email be sent.
Will this work? (Both being able to access the timer to cancel it, and the timer firing as expected if not canceled?) Is there a better or more .NET-appropriate way to implement this requirement? Apologies for the vague scope of this question; I've had no luck with Google or searching SO, though my unfamiliarity with working with timers might be hindering my searches.
Thank you!
The root of your problem is architectural. You should probably give more thought to how your server-side is designed and how the client-side design and the server-side designs compliment one another. For starters, persistent state, the ability to run some background tasks, and the utilization of locking functionality (such as C#'s lock keyword) when accessing that persistent state would help in producing a more extensible and flexible design. How you design those features and how your client-side interacts with is up to you. One approach would be to have the API controller write to the persistent state, using locking to prevent concurrent writing, and then using a background task to monitor that persistent state and fire certain actions when necessary. Play around with designs and figure out what works for your needs. Good luck with your application.