Over the last few weeks I was tasked with developing a ticketing system specific to my companies needs. Alright, not a huge deal.. Now I am onto a little trickier subject that I just can't wrap my head around completely.
Notification System based on a tickets last update time.
Alright so as we all know in a ticketing system we have tickets, lots of them.. Each of our tickets have a ticket "state" such as "Waiting on Client", "Pending Shipment" etc. These states have different thresholds I.E: 60 minutes, 120 minutes..
Basically I have a server application that runs every two hours. It loops through all the open tickets in the system, checks their ticket state and threshold and if the LastUpdate time is outside of my threshold of 60 minutes then the system fires off a notification saying that this ticket hasn't been taken care of and someone needs to get on top of it. Alright great, so that means every two hours the system runs it will check the time, if the ticket does not comply with its threshold then a level 2 notification gets sent out. The same process applies for notification 3.
The problem with this scenario is that what happens when Friday rolls around? There may only be 3 tickets that have notifications that need to be sent by the close of business Friday. However when Monday rolls around and this system runs again, it is going to find every ticket out of compliance which means we will more than likely have over 100 tickets in peoples mailbox. This seems like such a common problem among any notification system that operates off a datetime.
Any suggestions?
EDIT: Now that I know it's a C# app..
When your application is deciding whether or not to send a notification.. first, check if it is the weekend:
if (DateTime.Now.DayOfWeek != DayOfWeek.Saturday && DateTime.Now.DayOfWeek != DayOfWeek.Sunday)
// start sending notifications.
Or, you could do this:
if (TimeSpanElapsedToSendNotificationFor(thisItem)) {
if (isWeekend()) {
thisItem.LastUpdate.AddDays(2);
persist(thisItem); // update the DB
return;
}
// send notification here..
}
So, first check to see if the desired notification time has passed. If it has.. double check if it's the weekend.. if it is.. add 2 days to the LastUpdate property on this item then exit the function. If its a weekday, it will continue processing. Using this second method, your very first check will be false on the second run-through for all jobs unless they are added on the weekend.
PS: Why don't you just use a scheduled task and only run it during work hours?
Related
I was developing one application where I want to retrieve the available rooms from the "All Rooms" of the outlook address book. I am able to retrieve all the room entries from "All Rooms" Address Entry List. And then able to search for individual room's availability by calling AddressEntry.GetFreeBusy().
But the problem I am facing is the time performance of the code. If the number of rooms is high(let's say 500) then the time take to search availability of the room(worst case scenario where available room locates near to last of the list) is very high.
Microsoft.Office.Interop.Outlook.Application app = new Microsoft.Office.Interop.Outlook.Application()
var allRooms = app.Session.AddressLists["All Rooms"].Cast<Microsoft.Office.Interop.Outlook.AddressEntry>().ToLis();
DateTime today = DateTime.Today;
foreach(var room in allRooms)
{
//the below function will return the room status in a string of 1&0 for an interval of 1 min
string status = room.GetFreeBusy(today, 1, true); //sequentially calling this method is costly. What improvement can I do here?
//process the status and make some if free for certain time period add to list of available list
}
The GetFreeBusy method accepts three parameters and the default value for the MinPerChar parameter is 30 minutes. But your code only checks the first minute of the appointment. You need to go over the whole duration of your meeting (at least 30 minutes). Take a look at the similar forum thread.
If you are a .Net Developer then use Microsoft Graph APIs for this purpose. I used
POST /me/calendar/getSchedule
POST /users/{id|userPrincipalName}/calendar/getSchedule
from to achieve this. You can login as your userid and use ME option or you can use application mode login to login and use {id|userPrincipalName} to get calendar details for a room.
This link provides the basics on how to login and have good examples for Graph in general.
https://developer.microsoft.com/en-us/graph/graph-explorer
Ref:
https://learn.microsoft.com/en-us/graph/api/calendar-getschedule?view=graph-rest-1.0&tabs=http
On the site I am currently working on, we would like to reserve all items in a basket upon a user adding/removing an item to the basket.
At which point if the user makes no further additions or subtractions to his basket after a set period of time, the items will be unreserved.
I know this could be achieved by giving each stock quantity a DateTime of when it was last reserved (the last time the basket was updated) and refreshing that time on every basket update.
Then setting a scheduled task for very minute going through all stock quantities and if they are more than X old they can be unreserved and added back in to main stock.
Is this the best way to achieve this or is there a more elegant solution than a scheduled task.
I am using MVC , and Azure for hosting (which has a task scheduler, not that I have explored whether it can perform this sort of task)
If you use your stock quantity DateTime value as flag, and put a DateAdd(...) in your stock selection filter to allow items that have aged back into stock back into your results you don't need to create a scheduled task to remove the DateTime value. There will be a trade-off in query performance because it's slightly more complex, but with fewer moving pieces you will have a less complex, and therefore more supportable approach.
Implemented the solution i thought was possible (Giving each item a "Last Modified" field and then using azure task scheduler , ran an action that processed all those with a datetime outside of a certain range. )
Seems to work fine.
We are developing a shopping cart application.
For every single user session i have to give the user 20 minutes after he adds first product to shopping cart to go to checkout process. If the user adds another product, i have to reset the clock and start 20 minutes from the beginning. ıf user doesnt do anything in 20 minutes, i have to end the session. If user goes to checkout process another clock for checkout process will start. It will be 15 minutes. But if he cancels the checkout process and comes back to store, first clock has to start where it was left..
Hope i am clear.
What approach I can use? Am I gonna use threads, sessions vs..?
Thanks alot.
You would want to use Session state for this. You can set a timestamp in the session everytime the user does something - for instance, adds an item / etc. Before you open any page, you would check the time and see if
(DateTime.Now - Session[LastAccessTime]) > new TimeSpan(0, 20, 0)
If it is greater, then show a message saying that the time expired, else continue on.
On the shopping pages, you can check for 20 minutes, on the checkout pages, check for 15 mins.
Check out this answer too: Session time out with Timer
You would definately use the session for this as mentioned by Shiroy - however I would have thought you could simply use the Session.Timeout property, setting it as appropriate as you enter different areas of your site.
I need some help with this..
This table I have has a date column in it, and when any of the dates in that column equal the servers date I need to tell my website/program to send out an email or perform some certain notification action to let the user know something.
I was thinking of having a program running on the server polling the data base a certain intervals but the problem with this is if the date is 01/31/11 10:30 AM and my interval is every 5 mins there potential for the polling to be inaccurate i.e. the poll polling at 10:35 AM. In other words I need the database to somehow notify something when "x" date has been hit exactly at that date.
I'd like to avoid having a 1sec interval checking the database as I think that would be a huge performance hit.
I'm using ASP.NET MVC 3 with MSSQL and LINQ Entity framework.
Any creative ideas?
You could use Quartz.net to setup those events. Quartz is pretty flexible and powerful - and it was meant for this sort of thing.
Do not have the database trigger the code. Have a trigger create a row in another table with information about what just happened.
Have a separate program periodically read from the second table to email users or whatever you need to do. Have that program delete the row from the table once it's done with the email.
I don't have any personal experience, but Sql Server CLR Integration might be the answer you are looking for. From the description it sounds like you can write almost anything that will compile against the .NET framework and deploy it to a sql server instance and Sql Server will be able to execute it. http://msdn.microsoft.com/en-us/library/ms254498.aspx
you either need to make use of a scheduler (e.g. DBMS_SCHEDULER in Oracle or SQL Server Jobs, etc) or find some third party tool like maybe Quartz.net as mentioned by another responder. Or maybe code something like the following into a polling app
select all jobs due in next 5 minutes, order by due date
while there are jobs
if the next job is due action it
else sleep for duration of interval till job due
loop
This is bit dirty, but I think it will give you the functionality you're looking for.
In Global.asax.cs
public DateTime LastMaxDateTime;
protected void Application_Start(object sender,EventArgs e)
{
LastMaxDateTime = GetMaxDateTime();
Thread bgThread=new Thread(BackgroundThread_CheckDatabase);
bgThread.IsBackground=true;
bgThread.Start();
}
private void BackgroundThread_CheckDatabase()
{
while(true)
{
DateTime dtMaxDateTime = GetMaxDateTime();
if(dtMaxDateTime > this.LastMaxDateTime)
{
//Send Notifications
this.LastMaxDateTime=dtMaxDateTime;
}
Thread.Sleep(5000); //5 seconds
}
}
private DateTime GetMaxDateTime()
{
//function that returns DateTime from something like "SELECT MAX(DateTimeColumn) FROM [MyTable]"
}
Basically, the code keeps track of the newest DateTime in your table and on each poll, checks to see if there's a newer DateTime in the database since the last time it checked. If so, you can send out your notifications. If you're not expecting many records in your table that could cause a race condition, then I don't see a problem with this as a quick solution.
Most efficient way to do it is to have an application that instead of polling runs event-driven.
For example, have a thread query the database for the earliest scheduled event and sleep until then. Then have another thread synchronously wait for a table change (e.g. in PostgreSQL this would be the NOTIFY/LISTEN statements) and signal the first thread to check if the earliest event has changed.
The easiest way is to keep track of the date of your last check. When you check again, pull all rows greater than the last check date and less than or equal to the new check date. To make sure you execute them, you could add a column for when the action was performed and update that. With an index on that new column there shouldn't be any performance problem with checking it every second for rows with a NULL DateExecuted.
You could also read ahead and sort the upcoming items by trigger date and do a Thread.Wait() until the next one comes up to be precise.
Im about to create a very simple online event reservation application and currently have 3 tables:
User
PK_UserID
UserName
Event
PK_EventID
EventName
EventDescription
EventStartDate
EventEndDate
SeatsAvailable
BookedEvents
ID
FK_UserID
FK_EventID
Do you have any experience of how to handle SeatsAvailable? I mean if SeatsAvailable is set to 5 and there are 5 users online and want to book event. And some user has started to fill out the form then changed his mind. Then seats in database can just leak. I was thinking about sessions - like to limit every user to 5 minutes to complete the booking but i dont really know if its good idea. Do you have any suggestions?
I dont really see your problem.
SeatsAvailable would be the total allowed seats, and the number of booked users would be the sum of the rows on BookedEvents.
in your procedure to enter a user to BookedEvents you would read the count of BookedEvents and SeatsAvailable in a transaction, if the event is full then the users gets a message saying the they are too late
am i missing something?
I would use your way as well, but I would reset the timeout everytime the booking is progressed (ie. new page). I know from experience you sometimes have to look something up or similar, and I really hate pages timing out in that case. You should be fine with a timeout.