I am creating an auction site in which the auction has a particular end date/time.
I have a javascript timer displaying the remaining time to the user and when this countsdown it fires and event to update the back end mongodb database to say the auction has completed and it informs the winning user and fires a CLOSE function.
How would you recommend doing this for auctions that aren't physically open in a browser at the time so the Timer event never creates this CLOSE event.
I wouldn't recommend this approach at all. Once I was working on a website and I needed to implement auctions. The project was in php so I wrote a php script which checks all auction rows in the database and looks for those with the timeEnd >= current time and sets their status to closed(The auctions table had int column for the status).
Then I set that php script to run as a cron job once every hour. So now the server automatically runs this server side script every hours and checks for out-dated auctions. The interval depends on the business logic of the app. For this project the auctions could only end or start to the beginning of every hour. This approach is far better than using javascript code that triggers the server script. One reason is that you can't trust client side code. Hackers could potentially get access to that javascript file and easily modify it. You should never let your server code depend on your client side code.
However, note that my approach is not the most ideal because depending on how much auctions your db have, the server script will still need time to process it and might take from a few seconds to couple of minutes to execute it.
For example if you have some auction that ends at 10:00:00 and the server script start executing at 10:00:00 and it takes 40 seconds to execute, the users could potentially find a way to place bid on those auctions in the interval of that 40 seconds. Your client side code should only take care for resetting the interface right at 10:00:00 so that users are not able to place bids. However, you should also make sure that the server-side code that handles your POST requests for placing bids, should also check if the auction end time is in the past before proceeding. If it only checks the status of the auction (opened or closed) it might get auctions that are ended with their status set to opened. The reason is that the cron job might still be processing the auctions and changing their status.
Another similar approach is to create service that runs on operative system level (probably c or c++ app) that would run constantly in the background and do the checks.
The good thing with the first approach is that most of the hosting companies already offer setting up cron jobs. One example is Bluehost.
For setting up windows based "cron jobs" read additional info on this post
I hope this makes it more clear to you how to handle the auctions.
Related
I was wondering what the best way of implementing a timer in the frontend would be.
The idea is to notify the user after 13 minutes of inactivity (= not made a request to the backend) that he will be logged out in 2 minutes.
My first attempt was to just use a Timer which is executed every second (I am doing this with Flutter web but it shouldn't make a difference) and counts down from 15 minutes.
Then we tested this internally and noticed that the Browser somehow stops JavaScript execution if the user switches to a different tab for a long time or if the computer goes into stand by such that the timer stops.
We already have a session timeout after 15 minutes from the backend, this is just to make the user experience better.
How would this be correctly implemented?
For short, I think it's impossible for only using frontend
As you examine, the javascript code will be stop whenever switching tab or close tab, computer stands by. So that it will not be good to use a timeout or something like that.
I used an idea before but not implemented it yet because I switched to simpler idea with sessionStorage. But you could see and somehow success with it: when last request is made, created a cookie with expire time is 13 minutes. If next request is made, clear old cookie and add a new cookie with 13 minutes too. If the request will not made during 13 minutes, when cookie expire, fire a event to annouce to user. To listening cookie change, I think there are a lot solutions out there. But for me, this idea is not so good so I forgot it.
If you can use a nodejs backend, you could try to use Server Send Event - SSE. This will create one-way sending data. Therefore you can stream a chunk of data. And the frontend will listen that streaming and decide whether to annouce to user.
I have a configuration page where the user can select at what time to receive certain information from my API, for example they could select to get the information every day at 5PM or every Friday at 5PM. After this is set, the user should receive a Slack message at the time they defined, for example, every day at 5PM they would receive a message...
I save the user's timezone so that I can send the message to them in Slack at the correct time for them.
That being said, how can I schedule this message to send out from my node.js app? I would have a few users in the system, all who would have likely chosen different times so I would need a timer per user?
The only thing I can think of is scanning all users in the system, getting their selected time and then sending the message to them...but this doesn't seem scalable.
I'm not looking for a complete solution for this, just some pointers for how to design this sort of functionality.
I also looked into Slack scheduled messages but this isn't exactly what I'm looking for. Note: I can already send messages to Slack, I'm more interested in how to build the timer mechanism.
Thanks in advance!
EDIT:
Did a bit more research and it looks like node-schedule could be an option to schedule jobs: https://github.com/node-schedule/node-schedule#readme
With using this package, is the approach that I scan all users in my database at let's say midnight everyday and schedule jobs based on their settings...then those jobs execute at their scheduled time and the user receives the message in Slack. Is this a good approach?
For the core logic I would suggest something like this:
Store the timing of delivery (e.g. 5 AM ever Friday) for every user in your database
Then have a worker process that is running on a regular basis, e.g.
every 5 minutes
When it runs it checks if there are any due messages to be delivered
If yes it sends the message with your API information to the user and store the last time of sending for the user
This approach is resilient to downtime. It will just resume sending due messages once the worker process is running again after a downtime.
It is also scaleable: If needed you can run multiple worker processes (make sure to design your workers to support concurrent processing, e.g. with transactions)
Some additional things to consider:
Would limit the number of messages sent per run to avoid timeouts and having too many workers running in parallel
You need some error handling if sending message to Slack fails
To avoid timezone complexities I would suggest to convert all timings to UTC for processing in your app
Is this a regular task? In other words, it's executed every day at the same time for user X? If so, node-schedule seems fine, and it can run the same job regularly, you just have to set it up properly via a cron-like string (see the instructions in the README). If a user changes their setting, you then modify the previous job. The downside with node-schedule is that you need to set it up everytime your application is loaded, which can take a while and consume lots of resources if you have too many users.
Alternatively, if the number of users is big or you prefer to keep your application stateless, you can set a number of slots for sending these messages (and run that in a separate process from your main application). Let's say, a slot every 30 min. Then you set timers for those time slots (using node-schedule if you like, it will be just 48 timers), fetch the list of users for that time slot from the database, and send the messages.
Overall, NodeJS/JavaScript is pretty efficient with this sort of timer-based scheduling. If you want an in-depth dive into the reasons, see this: https://nodejs.org/de/docs/guides/event-loop-timers-and-nexttick/
You also need to consider what happens in case your application suffers from downtime. Should users be guaranteed to receive those messages, even if they are late? But that's another story :-)
I have a schedule manager web application where the system will check every hour if current time is passing the due date that stored in database and will send an email if the current time pass the due date even if the user doesn't open the web app. Can sails js alone do something like this?
You'll probably want to schedule a cron job which executes a script at a set interval to do this for you.
You can read up on cron and decide what works best for you; in general you'll probably want to have a separate script that is executable from the command line (such as a send_emails.js which you can execute with node send_emails.js).
I'm have a very long process in a php script (generate a huge pdf).
I have a button in my HTML page that launches the php script and I'd like to show a kind of progress bar or at least an animated gif and when the php script is over, display the generated pdf.
The generation of the pdf may last 15 minutes so the php engine exits in timeout and the browser too.
I there a way to declare a kind of client-side callback that would be invoked as soon as the server side process is over ?
Thanks for your replies
Edit :
Thanks for your replies :)
If I well understand, I must launch the process on server-side and "detach" my client i.e do not wait untill the process is over. Instead, my client should periodically check the progression of server-side process. Right ?
If so, I may use the following scenario :
The client sends an ajax request to the server. The server launches
the process and returns a guid to the client. This guid identifies
the job.
The client periodically checks the progression of the job
via an Ajax request, from its guid.
Once the job is over, the client can issue a last Ajax query to
download the PDF
That means that the server must save the generated PDF on its disk and wait for the final Ajax request to send the file and delete it, right ?
For something as long as 15 minutes, I wouldn't even use web sockets for this. 15 minutes is a long time and there's really no telling what the user is going to be doing in the meantime. A disconnected notification process is probably going to be more reliable in this case.
Consider something like:
User initiates process, whereby a record is stored in the database "queueing" the process to take place.
User is immediately presented with a page indicating that the process has been queued and that they can continue to use the application.
A separate application which runs periodically (every minute? every few minutes?) checks for "queued" processes in the database, updates their status to "in-progress" (so subsequent runs don't also pick up the same records), and processes them.
As each process completes, it's either removed from the database or updated to a "completed" status.
The user is otherwise notified that the process is complete.
This final notification can be done a number of ways. An email can be sent to the user, for example. Or consider a user experience similar to the Facebook notification bar. Each page in the website can check for "completed" processes when the page loads and present a "notification" in the UI which directs the user to the result of the process. If users spend a lot of time on any given page then this would be a good place to use web sockets or long polling via JavaScript to keep checking for completed processes.
The main thing is to separate the user interface from the long-running process. Web applications by design aren't suited for processes which run for that long. By separating the concerns the web application can focus just on the user interface and the command-line application can focus on the processing. (As an added bonus, this would prevent users from over-loading the server with too many concurrent processes. The command-line application can just run one record at a time, so too many concurrent processes just slows down the response, not the server.)
as #David said, but no one has covered the progress bar, the implantation of this depends on what you know ( you being the application creating the pdf ).
Do you know the size of the pdf when complete.
Do you know how long
it will take to generate.
Do you have code where you can hook into
to update the progress.
The application needs a way to know when to update the completed percentage, and by how much. If you can do that then you can either store the progress in the database with the script that crates the PDF and read it on a user facing page, or store it in a file, etc..
jQuery UI progress bar is easy to use, but you will have to know what percentage is done to be able to tell the end user.
After that it is a pretty simple matter of using ajax (jquery $.post ) and a file, that's how i do it. I just wright a simple text file with a number representing the completion percent. Load it via ajax and feed it to the jquery ui progress widget.
I am currently working on an auction script using node.js and socket.io.
The site will have 500-1000 logged in users viewing a single page during the auction. Only one item will be on sale at any one time, similar to a real auction held in an auction house.
I will be broadcasting a countdown timer to all of the signed in users from the server to the client. On the server side I will be using setInterval() of 1 second to countdown to the auction end time. Apart from this the only other message being sent across will be the current bid being passed from a single client to the server then broadcast to all.
Will this be a reliable way to do this? And will it be able to handle the usage on the server?
If not is there a way which would be better?
Thanks Shane
For timer value, keep updating your local timer per second on server side itself. Whenever any user comes in, give him this value and also total value of timer. Then client will start their own timers locally as per comment by dandavis, but keep some interval like 15 or 10 seconds on server side on which server will broadcast the current timer value so that client will sync accordingly.
In short, server will broadcast every after 10(n:you decide) seconds but it will be updating timer variable per second locally. Whenever client comes in, it will get total timer value and current timer value.
Rest functionality of broadcasting the current bid can be done in normal way.