Recently I was creating an auction site. I want to make it like when user bid the item, there is a AI bidder to upbid the user. For say user bid on item1 after 5 seconds the AI bidder will auto bid the item1 as well. Any idea how can I execute it automatically after 5 seconds?
A simple and efficient solution could be to store all future bids with a "due date" and all the information to bid in a list. Then every 5 seconds or so you could loop through the list and make all bids if they are due. This system would be extensible and would work for a large amount of bids. Of course, ideally this would run in a different thread.
It's a bit like re-implementing a "cron-like" job management in your servlet but I can't see any solution that would fit your needs out of the box.
I am not sure I answered your question, hope so.
Regards,
Stéphane
Depends on what technology you actually use, you can use EJB timers for that for example, just start the timer ejb when a new bid occurs, on timer timeout (after some time) the method executes and updates the bid.
Standard servlet solution
Create a Filter, map it to the url pattern of your bid servlet.
In your doFilter(), after your filterChain.doFilter() call (ie, after the request has been processed by the servlet/JSP), schedule an action for 5 seconds in the future (you can use the standard java ScheduledExecutorService)
In the Runnable implementation you schedule (your task), place the AI bid.
In my opinion:
If user bid, and after 5 secs, it sends the request to the server, i prefer JS with setTimeout(). (Of course it required Browser's JS - read more abt this in W3School).
Otherwise, you can use an array (or smt like that) act as an queue (in server side), after each 5 secs, it's lock the queue (sync), and check for which inserted 5 secs ago, and process it (or use an Thread for each time an event requests to server). Basically, you can use a thread to do that trick? (Did u mean this?).
Related
In a microservice architecture, suppose there is a business scenario where a user purchases something that will expire after two years, and the system needs to notify the user a little bit in advance.
In this case, how should we handle the situation so that the users can be notified on time even if there are many users who need to be notified?
For example, using a delayed queue of message queue will cause the messages to pile up when there are many users; using a timed task, too many users will overload the server CPU.
Is there a good way to do this?
While "microservices" do not inherently mean "REST", they usually are. And in REST you shouldn't store in memory anything that needs to survive more than one request. Two years is an extreme case, but even if it is for just 10 minutes, it should probably go to the DB.
Building up a queue for two years will just be very impractical and likely to fail if the queue contents are not persisted somewhere. Since you mention purchases I am assuming you have some sort of data store to record them either in sql or no-sql.
You can simply add purchase date/time column(s) to the table to make life easier. If you volumes are low enough for daily purchases then I would start with date based lookup only. You will need a scheduled execution of some service method say at 6am everyday that looks up purchases close to expiry i.e 7 days before 2 years purchase_date = now - 723days and then send rest request somewhere or publishes an event or jms message with order number and purchase_date as content for each purchase order. This will then be picked up by event/message listener somewhere and processed accordingly i.e. send a notification to customer. To avoid sending duplicate notifications you should also persist the expiry notifications in a database and ensure you check that notification has been sent for purchase id before sending it again.
If you ever reach a situation where you are processing thousands of orders a day and don't want to publish large number of events in one go then extend the functionality to filter by purchase timestamp and process chunks of purchases multiple times a day by changing the lookup condition.
This is just general idea of such requirement and you will have to fine-grain a lot of implementation details such as what happens if your email server is down.
You can use quartz job and configure it to use persistent mode in database (JDBC JobStore) to not loose information and also it is suitable for clustering mode.
Quartz checks periodically the database for the nearest task (configurable parameter) if the time comes, it will process the notification.
You can configure the thread pool size in order to avoid overload.
I have integration with video stream provider. The flow is following: user requests a stream url, next we on behalf of user, request it from stream provider and return to the user. Next, we should prolong the stream id (session) every 10 secs. To minimize interaction with the client and because of slow network, we want to do this session prolongation on behalf of the user. So let's say, user will trigger one request per 2-5 mins, at the same time server will trigger session prolongation requests every 10 secs.
The question is in possible design of such service. I have not found better solution other than just simply iterate over all available session keys periodically and call prolongation service.
But this approach has disadvantages when user count will be really big it could slow down processing. Also, it is hard to scale with such an approach.
Maybe you have ideas about how to overcome this? Or please propose a better solution
I would write the keep alive as a single self contained piece of code, that will call the keep alive every x number for seconds for y amount of time before ending itself, where x, y and the keep alive endpoint are startup parameters.
Each time the user triggers a request - kick one of these off in the background. How you package that is determined on your deployment environment and how you intend to manage scaling out (background thread, new process, server-less function, etc.).
You may need to maintain some state info in a cache for management purposes (don't start a new one if one is already running, hung process states, etc.).
We have an external SOAP based web-service which provides information regarding customer's gift card balance when presented with an Id. This Id is stored in our database.
The requirement is to find out the balance for all such customers who has this Id flagged and then send them an email. This logic is supposed to be run as a scheduled job once every alternate day.
When we queried the DB, we found out that there are more than 5000 such customers who have this Id flagged. Unfortunately, the web-service will NOT accept a list of Ids, and can only give information about a single customer in one network call.
Now, our doubt is whether it will be a good idea to loop through 5000 Ids and call the web-service in this loop as many times.
As a test run, when we called the web-service for 500 Ids, it completed in 3.7 minutes and 1000 Ids 7.25 minutes. By this measure, we can guesstimate that for 5000 Ids, it should roughly take 40 minutes.
Our web-application is JavaEE 6 stack and DB is Oracle.
Is there a better way to do this ? Any suggestions are welcome.
Thanks.
If you could write a deterministic function that takes the input of the customer id and that gives you a number from 0 to 47 representing the number of hours in the 2 day cycle of sending these email alerts, you could shard the email sending and convert it to a job that runs every hour.
I know that is changing the requirements a bit, but there isn't much difference between sending a batch every 2 days and a smaller batch every hour. Each customer who remains on your list would continue to get emails every 2 days.
Another possibility is to send queries to the web service in a multi-threaded manner.
The web service provider should really think about changing their interface.
Unfortunately, the web-service will NOT accept a list of Ids, and can
only give information about a single customer in one network call.
You should really take contact with the service provider to get a suitable solution.
As workaround, if making multiple concurrent invocations is allowed by the SOAP WS, you could make multiple invocations of the WS by multiple Threads.
To achieve that, create a Runnable or a Callable implementation that performs the invocation to the WS with a specific id.
For example to perform concurrently 10 invocations of the WS, with Callable and ExecutorService, you could do something as :
MyWs myWs = ...; // web service stub
List<Long> ids = ...; // ids to search
List<Callable<Double>> callables = ids.stream()
.map(id -> (Callable<Double>) () -> myWs.getBalance(id))
.collect(Collectors.toList());
ExecutorService executorService = Executors.newFixedThreadPool(10)
List<Future<Double>> balanceFutures = executorService.invokeAll(callables);
Of course adjust the number of invocations according to the CPU of the machine that runs the JVM.
I want to run some kind of Thread continuously in app engine. What the thread does is
checks a hashmap and updates entries as per some business continuously.
My hashmap is a public memeber variable of class X. And X is a singleton class.
Now I know that appengine do not support Thread and it has somethinking called backend.
Now my question is: If I run backend continiously for 24*7 will I be charged?
There is no heavy processing in backend. It just updates a hashmap based on some condition.
Can I apply some trick so that am not charged? My webapp is not for commercial use and is for fun.
Yes, backends are billed per hour. It does not matter how much they are used: https://developers.google.com/appengine/docs/billing#Billable_Resource_Unit_Costs
Do you need this calculation to happen immediatelly? You could run a cron job, say ever 5 min and perform the task.
Or you can too enqueue a 10 minutes task and re-enqueue when is near to arrive to its 10 minutes limit time. For that you can use the task parameters to pass the state of the process to the next task or also you can use datastore.
I am trying to decide if use a java-ee timer in my application or not. The server I am using is Weblogic 10.3.2
The need is: After one hour of a call to an async webservice from an EJB, if the async callback method has not been called it is needed to execute some actions. The information regarding if the callback method has been called and the date of the execution of the call is stored in database.
The two possibilities I see are:
Using a batch process that every half hour looks for all the calls that have been more than one hour without response and execute the needed actions.
Create a timer of one hour after every single call to the ws and in the #Timeout method check if the answer has come and if it has not, execute the required actions.
From a pure programming point of view, it looks easier and cleaner the second one, but I am worry of the performance issues I could have if let's say there are 100.000 Timer created at a single moment.
Any thoughts?
You would be better off having a more specialized process. The real problem is the 100,000 issue. It would depend on how long your actions take.
Because its easy to see that each second, the EJB timer would fire up 30 threads to process all of the current pending jobs, since that's how it works.
Also timers are persistent, so your EJB managed timer table will be saving and deleting 30 rows per second (60 total), this is assuming 100K transactions/hour.
So, that's an lot of work happening very quickly. I can easily see the system simply "falling behind" and never catching up.
A specialized process would be much lighter weight, could perhaps batch the action calls (call 5 actions per thread instead of one per thread), etc. It would be nice if you didn't have to persist the timer events, but that is what it is. You could almost easily simply append the timer events to a file for safety, and keep them in memory. On system restart, you can reload that file, and then roll the file (every hour create a new file, delete the older file after it's all been consumed, etc.). That would save a lot of DB traffic, but you could lose the transactional nature of the DB.
Anyway, I don't think you want to use the EJB Timer for this, I don't think it's really designed for this amount of traffic. But you can always test it and see. Make sure you test restarting your container see how well it works with 100K pending timer jobs in its table.
All depends of what is used by the container. e.g. JBoss uses Quartz Scheduler to implement EJB timer functionality. Quartz is pretty good when you have around 100 000 timer instances.
#Pau: why u need to create a timer for every call made...instead u can have a single timer thread created at start up of application which runs after every half-hour(configurable) period of time and looks in your Database for all web services calls whose response have not been received and whose requested time is past 1 hour. And for selected records, in for loop, it can execute required action.
Well above design may not be useful if you have time critical activity to be performed.
If you have spring framework in your application, you may also look up its timer services.http://static.springsource.org/spring/docs/1.2.9/reference/scheduling.html
Maybe you could use some of these ideas:
Where I'm at, we've built a cron-like scheduler which is powered by a single timer. When the timer fires the system checks which crons need to run using a Quartz CronTrigger. Generally these crons have a lot of work to do, and the way we handle that is each cron spins its individual tasks off as JMS messages, then MDBs handle the messages. Currently this runs on a single Glassfish instance and as our task load increases, we should be able to scale this up with a cluster so multiple nodes are processing the jms messages. We balance the jms message processing load for each type of task by setting the max-pool-size in glassfish-ejb-jar.xml (also known as sun-ejb-jar.xml).
Building a system like this and getting all the details right isn't trivial, but it's proving really effective.