I built a bidding website for a client in which a user posts an item and sets the auction duration. The item is first in Pending state until an admin approves it or after 12 hours have passed since the user first posts it. From then on, the item gets Published and other users can bid on it. Once the auction period is over, the item should be Closed and the highest bidder wins the item...
In addition to that, I need to send email notifications...
To the admin once a new item is posted.
To the winner once he wins an item.
To the item's owner once the auction is closed.
To the admin once an auction has been closed and there was a winner (i.e: people actually bid on it).
Currently what I'm doing is to call some method in my business layer which checks whether there are any pending items that have passed the 12 hours period to make them published, and whether there are published items that have passed their auction duration to close them. This method is called from several places such as the website's home page, the item's search page and others... This is actually causing me problems (Refer to this question). So I think it's worth finding an alternative solution that would help me get rid of all these issues that are most likely due to poor design.
Should I centralize this by calling that method from one single place and sending the emails accordingly?
Should I delegate this whole thing to some sort of scheduled task? In this case, what time-frame would be reasonable to run this task?
Any other suggestions?
Should I delegate this whole thing to some sort of scheduled task? In
this case, what time-frame would be reasonable to run this task?
Yes, this seems like the best approach. Offload the email sending to a separate process than your ASP.NET MVC application. As far as the time-frame is concerned, this will depend on your business requirements. You may take a look at Quartz.NET which could be used as a task scheduling mechanism.
You should definitely offload this to another process like a scheduled task or a service. You don't say how many users you currently have or how many are likely to be doing something at the same time, but if you find your userbase to be growing having loads of emails being sent out on a web request will eventually time out.
A separate task/service will also allow you greater control over what emails get sent and when.
Related
I have an asp.net web service which is like a reservation system and cannot reserve the same seat by multiple persons and the eligibility for the reservation is based on some other table values in SQL server. I plan to use SQL server queue processing as mentioned here. My customer wants to do this in a synchronized call, means we want the result in the same web service method call. My question is how efficient it to allow a synchronized method call to process a queue and wait until the queue return values (by means of a loop within a time span or so). Please advise the best possible approaches to achieve this.
You are stepping in the XY problem trap. Your primary goal is to make sure no seat can be reserved twice. You should rethink your approach of using a queue is the appropriate solution to this problem. A queue is great to efficiently use your processing resources on a background task. For real-time processing (like yours) it will create more problems that it solves.
It seems like you want to avoid the race condition that occurs when multiple users try to access the same seat twice. The queue doesn't solve the problem, you just move it to the enqueing phase. The one who enters the queue first wins. At the end you have added an unnecessary complication that doesn't bring you any benefit.
A much simpler solution to your problem is to create a unique key on your DB that makes sure that no seat can be reserved twice. Once you try to reserve a seat that has been taken just a moment ago, you will get an SQLException with the error number 2627. You can then prompt the user that the seat is taken.
I have a component which imports several files into a large database. The process takes long time, and in many cases can require user dialogs, like "Is this A or is this B? (Button A, Button B)" and so.
The component was written with a desktop application in mind, and now there's a need to migrate this component into an ASP.NET MVC 5 application. The only serious issue I see is to manage these synchronous user dialogs. What's more, by design the synchronous user inputs are sometimes depending on previous user inputs, etc.
I know that synchronous coding "doesn't fit" into the web world at all, but redesigning the whole large algorithm to be somehow asynchronous about user dialogs would be a huge work and would lead to lots of new testing, etc.
Is there any technique which would be applicable in this case without needing to rewrite every user input to asynchronous?
As a note, the operation will be used by very limited users and quite rarely, say 1-2 times a week, so general performance is not an issue.
What I am thinking about
Start the long operation via an AJAX call, the server would start a new thread and return some token which "points" to the operation.
The client-side would poll the server with this token for example in every second if there is new user-input request.
When a user input is needed, the operation would wait for X (for example 120) seconds to get an answer, otherwise would cancel itself.
If the client-side gets a new user-input request, it will show the dialog, gather the result and send it back to the server, so the operation can continue.
Is this a viable design, or is there any better solution?
I am basically creating a site for recruiters. One of the functionality in my application requires posting to Facebook periodically. The posting frequency can be from 0(Never) to 4(High)
For Eg. If a recruiter has 4 open jobs and he has posting frequency set to 4, each job should be posted as per it's turn: 1st job on 1st day, 2nd job on 2nd, 3rd job on 3rd etc, on 5th day again 1st job (round robin fashion).
Had he set the posting frequency to 2, two jobs would be posted daily (thus each job would be posted every 2 days)
My only question is what type of threading should I create for this since this is all dynamic!! Also, any guidelines on what type of information should I store in database?
I need just a general strategy to solve this problem. No code..
I think you need to seperate it from your website, I mean its better to run the logic for posting jobs in a service hosted on IIS ( I am not sure such a thing exists or not, but I guess there is).
Also you need to have table for job queue to remember which jobs need to be posted, then your service would pick them up and post them one by one.
To decide if this is the time for posting a job you can define a timer with a configurable interval to check if there is any job to post or not.
Make sure that you keep the verbose log details if posting fails. It is important because it is possible that Facebook changes its API or your API key becomes invalid or anything else then you need to know what happened.
Also I strongly suggest to have a webpage for reporting the status of jobs-to-post queue, if they failed what was the causes of problem.
If you program runs non-stop, you can just use one of the Timer classes available in .NET framework, without the need to go for full-blown concurrency (e.g. via Task Parallel Library).
I suspect, though, that you'll need more than that - some kind of mechanism to detect which jobs were successfully posted and which were "missed" due program not running (or network problems etc.), so they can be posted the next time the program is started (or network becomes available). A small local database (such as SQLite or MS SQL Server Compact) should serve this purpose nicely.
If the requirements are as simple as you described, then I wouldn't use threading at all. It wouldn't even need to be a long-running app. I'd create a simple app that would just try to post a job and then exit immediately. However, I would scheduled it to run once every given period (via Windows Task Scheduler).
This app would check first if it hasn't posted any job yet for the given posting frequency. Maybe put a "Last-Successful-Post-Time" setting in your datastore. If it's allowed to post, the app would just query the highest priority job and then post it to Facebook. Once it successfully posts to Facebook, that job would then be downgraded to the lowest priority.
The job priority could just be a simple integer column in your data store. Lower values mean higher priorities.
Edit:
I guess what I'm suggesting is if you have clear boundaries in your requirements, I would suggest breaking your project into multiple applications. This way there is a separation of concerns. You wouldn't then need to worry how to spawn your Facebook notification process inside your web site code.
We are looking to develop an email notification service where emails can be scheduled daily, weekly, or hourly based on certain actions that happen within our system (User Registration) or summary emails sent every Friday for example.
What is the best way to handle making sure duplicate emails are not sent? We thought about maybe having the application write a record to a queue whenver a system action happens but this would seem to have one more point of failure. Or maybe just making all notifications data driven, for example, select all users where created on date is greater than now. But with this scenario we need a way to make sure if the service runs again duplicate emails are not sent..
any ideas would be great!
My 2 cents
1) Queues. Queues are great for the tasks where you want to have a 'single entry and single exit' type of architecture. Queues decouple the systems and allow you to load balance the system. They are usually used with the multiple workers on one and another end. You will just add (maybe a lot) of messages to the queue, and later run a bulk dequeue. IMO that is irrational memory and resource consumption.
2) Data-driven via Users. Much easier to implement, however for each notification you will check every user and will put heavy load on db.
3) Data-driven via UserNotifications. Alternatively, you can create a separate table UserNotifications, where each user will be added once he has registered. It is much easier to select the needed users within given time frame and you don't store them in memory. Once notification sent, you remove the user from UserNotifications table.
I feel my question is somewhat straight forward, but I've added some details of my problem in the "Background Info" section in case it is too vague.
Question
How does the WorkflowServiceHost determine that a persisted activity, that is Idle due to Delay, has reached the Delay timeout? Does it load it into memory and check every so often, or is there something else happening here?
Background Info
So, I'm a bit new to workflow and I'm trying to determine the feasibility of using it for a business process that would use a 3 month delay. Basically, the business process is to allow a customer a 3 month trial of upgraded service. To accomplish this, I'm thinking of implementing a Pick activity that splits between a WCF Receive ("Cancel upgrade receive") and a 3 month Delay activity. If the delay expires, they are upgraded permanently and billing is updated. Alternatively, if the cancel is initialized then, well... yeah, you get the idea :)
So.... my concern is in regards to how Delay is implemented when using SQL workflow persistence. I don't want to end up w/ 500 activities in the persistence store that have to be loaded every 10 minutes for 3 months in order to check if the Delay activity expired.
According to https://msdn.microsoft.com/en-us/library/ee829473(v=vs.110).aspx, the way this works is that:
The SQL Workflow Instance Store runs an internal task that periodically wakes up and detects runnable or activatable workflow instances in the persistence database
An activatable workflow is a workflow that meets either of the following criteria:
The instance is unlocked and has a pending timer that has expired.
The instance has an expired lock on it.
The instance is unlocked and its status is Executing.
So the suggestion of the OP (" Does it load it into memory and check every so often") is correct.
I have not confirmed this behavior myself, but stumbled upon this thread as I was looking for an answer to the exact same question, then found the relevant MSDN article, which I wanted to share with you.
Hope this helps.
I was looking at this same problem with a much smaller window of time. I still would love to hear if/how you resolved this using workflow?
I am using WF4 and a pick as you stated above and then my solution is to try and use appfabric for reinitialising the workflows based on the delayed timer. This is based on what I read here:Hosting workflow services with durable timers / delays and this here: Activation of workflow service instances
I have tested that the pick works perfectly with a delay on one side, but now I have to test appfabric out.
Perhaps, I will come back with an update here on how it works out. Or you can give me some insight?