Java + spring - run actions in infinite loop with random interval - java

I need to simulate a widget that shows purchases in real time.
To increase statistics, I want to supercharge real purchases with fake data, that needs to be emit in random interval.
All the events (real and fake ones) go to the message channel and get processed and then send to frontend.
So I need to come up with some service, that I can control (run and stop)
public class FakeDataGenerator {
private boolean run;
private Queue queue;
public void run() {
run = true;
while(run) {
queue.push(generateFakeOne())
TimeUnit.SECONDS.sleep(ThreadLocalRandom.current().nextInt(1, 30));
}
}
public void stop() {
run = false;
}
private Purchase generateFakeOne() {
// ... some faking logic
}
}
generator.stop();
where generator.run(); will start emitting events with random interval, and generator.stop(); will allow me to stop it any time
Is there any tool to accomplish such task? I'm not happy with using an infinite loop.

If you are using spring-boot why don't try using just #Scheduled(fixedDelay = 1000) annotation example
Example
#Scheduled(fixedDelay = 1000)
public void scheduleFixedDelayTask() {
System.out.println(
"Fixed delay task - " + System.currentTimeMillis() / 1000);
}

Use some of Spring Executor and give it a task to execute. You can control it by the executor reference

Related

How to synchronize parallel processes into a web service?

I need to develop a web service operation with CXF 3 hosted by Tomcat 7. Our model layer is Spring 3.
This operation calls 16 other web services hosted by distant servers. We need to wait all responses in order to construct the response of our own operation.
We currently call each distant operations sequentially. Of course, we have response time issue. I think we should parallelize our operation inner calls and synchronize the different responses.
What kind of multithreading implementation can be safe? What can we do to make it better?
I'd use Java's generic Futures and a Spring's #Async methods in a #Service.
In short, you call the services sequentially and get all results as Futures, and then you simply check whether all the futures have finished proccessing. You can also do some work with partial data if there is such possibility.
Here's a simple example on how to do it. A sample service from the link:
#Service
public class GitHubLookupService {
RestTemplate restTemplate = new RestTemplate();
#Async
public Future<User> findUser(String user) throws InterruptedException {
System.out.println("Looking up " + user);
User results = restTemplate.getForObject("https://api.github.com/users/" + user, User.class);
// Artificial delay of 1s for demonstration purposes
Thread.sleep(1000L);
return new AsyncResult<User>(results);
}
}
And a method using it:
#Override
public void run(String... args) throws Exception {
// Start the clock
long start = System.currentTimeMillis();
// Kick of multiple, asynchronous lookups
Future<User> page1 = gitHubLookupService.findUser("PivotalSoftware");
Future<User> page2 = gitHubLookupService.findUser("CloudFoundry");
Future<User> page3 = gitHubLookupService.findUser("Spring-Projects");
// Wait until they are all done
while (!(page1.isDone() && page2.isDone() && page3.isDone())) {
Thread.sleep(10); //10-millisecond pause between each check
}
// Print results, including elapsed time
System.out.println("Elapsed time: " + (System.currentTimeMillis() - start));
System.out.println(page1.get());
System.out.println(page2.get());
System.out.println(page3.get());
}
I would use a traditional approach using join() to wait for the threads to finish instead of polling (I don't like polling pattern too much).
Kind of this for a generic thread to replicate:
public class ThreadedWebServiceRetrieval extends Thread {
private List<ResultObject> resultList;
private GenericWebServiceStub stub;
public ThreadedWebServiceRetrieval (List<ResultObject> resultList, GenericWebServiceStub stub) {
this.resultList = resultList;
this.stub = stub;
}
public void run() {
resultList.add(stub.retrieveData());
}
}
And this for the parallel retrieval code:
// ... Controller/Service stuff
List<ResultObject> resultList = new LinkedList<>();//Diamond operator
List<Thread> webServiceList = new LinkedList<>();
webServiceList.add(new ThreadedWebServiceRetrieval(resultList, stub1));
//...
webServiceList.add(new ThreadedWebServiceRetrieval(resultList, stubN));
for (Thread thread : webServiceList) {
thread.start();
}
for (Thread thread : webServiceList) {
thread.join();
}
// resultList is fulfilled
Time of this approach should be +/- longest retrieval.
I made the code VERY generic (overall in the Thread implementation) but it's intentional to fit most cases.
Enjoy!

Waiting two minutes to call a method

I'm working on a Minecraft Bukkit plugin, I know how to handle events and everything, but I'm not sure how to do this. I haven't actually written the code yet so here's a basic example of what I want to do:
public void playerDead() {
runCommand(commandHere)
//Wait 2 minutes.
runCommand(otherCommandHere
}
I just need the part to wait two minutes. Everything else is covered.
EDIT2: Seems I need to reset the delay to the beginning if someone else dies while it's going. Any suggestions?
Since I see you want to perform your action after the player has died. Then for sure you don't want to halt the main Thread with Thread.sleep(x);
What you can do is create a cooldown for the player that passed away.
public Map<String, Long> cooldown = new HashMap<String, Long>();
Long time = cooldown.get(player.getName());
if(time - System.currentTimeMillis() > 10*1000)
cooldown.put(player.getName(), System.currentTimeMillis());
else
int remains = (int)Math.floor(10 - System.currentTimeMillis());
Code reference here.
Or you can create your task to run like this:
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
{
public void playerDied()
{
// Your code here.
}
}, <delay in ticks>);
Get a reference to your plugin and pass it as the parameter plugin. Or if you are lazy just write it inside the plugin and pass it this.
You should use the BukkitScheduler provided by Bukkit.
You have to save the BukkitTask object returned by the Scheduler.runTaskLater(...) method to use it later.
Every time playerDead() is called, you can reset the delay by cancelling and restarting the task.
BukkitTask task;
public void playerDead() {
// Command here
if (task != null) {
task.cancel();
}
task = getServer().getScheduler().runTaskLater(Plugin, new Task(), 2400L);
}
public class Task extends BukkitRunnable {
#Override
public void run() {
// Other command here
task = null;
}
}
You may try like this:
new Timer().schedule(new TimerTask() {
#Override
public void run() {
runCommand(commandHere);
}
}, 120000);

Java Serial Data Event Processing

The below code details an id read when a serial event happens,an id is generated every fews seconds when the device is powered on(Serial Event), and no serial data is received when it is powered off .problem is i need a url call to be sent once when the id is received and once when not visible(powered down).
I believe im close but cannot seem to get it right.I would be very grateful if someone could help with this and how to set flags and scheduler to achieve the above case and possibly explain where im going wrong.
int numberOfEmptyIds = 0;
int maxNumberOfAttempts = 5;
boolean urlSent = false;
long timeoutInMillis = 10000; // let's say 10000 millis, equivalent to 10 seconds
Timer timer = null;
public void connect(String portName) throws Exception {
...
scheduleTimer();
}
public void serialEvent(SerialPortEvent evt) {
if(evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
while(in.read(buffer) > -1) {
String asHexStr = DatatypeConverter.printHexBinary(buffer);
if(asHexStr.contains("FB1")) {
scheduleTimer();
numberOfEmptyIds = 0;
} else {
numberOfEmtyIds++;
if(numberOfEmptyIds == maxNumberOfAttempts && !urlSent) {
// send the url here
}
}
}
} catch (IOException ex) {
// Log the exception here
}
}
}
private void scheduleTimer() {
timer = new Timer("Timeout");
TimerTask task = new TimerTask() {
#Override
public void run() {
if(!urlSent) {
// send the url here
}
}
};
timer.schedule(task, timeoutInMillis);
}
Problem is i need a url call to be sent once when the id is received
and once when not visible(powered down).
The second part is done by the timer, if no data arrives to the serial port then the scheduled task will sent the URL (if not sent yet). In my answer to your previous question I forgot to cancel the timer when the task is re-scheduled :
private void scheduleTimer() {
if(timer != null) {
timer.cancel();
}
timer = new Timer("Timeout");
TimerTask task = new TimerTask() {
#Override
public void run() {
if(!urlSent) {
// send the url here
}
}
};
timer.schedule(task, timeoutInMillis);
}
This way there would be a single scheduled task. From Timer.cancel() javadoc:
Terminates this timer, discarding any currently scheduled tasks. Does
not interfere with a currently executing task (if it exists). Once a
timer has been terminated, its execution thread terminates gracefully,
and no more tasks may be scheduled on it.
Note that calling this method from within the run method of a timer
task that was invoked by this timer absolutely guarantees that the
ongoing task execution is the last task execution that will ever be
performed by this timer.
About the first part you can manage it with boolean flags just like urlSent. If you need to send the URL just a single time then you can have a flag for the URL sent by ID arriving and another flag for URL sent due no data (or empty ID's) received.
Edit
Based on the flow-chart you've posted here and shown below:
Enter description here http://dl6.fileswap.com/storage_previews/02112014/54cd147697479d29c43c530b93d5fa83/52fe9168/aW1hZ2UvanBlZw%3D%3D/4cf59787af56f18847df6235cdc20816.jpg
You maybe can change your current approach using Timer.scheduleAtFixedRate() method to check at a fixed rate of time a if the serial port stops reading the ID. As you need to send the ID received notification just once then you may set urlSent flag to true when this URL is efectively sent. Also I think you can get rid of check if the received data doesn't contain the expected ID. Something like this:
boolean urlSent = false;
long lastIdArrivalTime = 0;
long timeTolerance = 60000;
long timeoutInMillis = 300000; // 5 minutes
Timer timer = null;
public void connect(String portName) throws Exception {
...
scheduleTimer();
}
public void serialEvent(SerialPortEvent evt) {
if(evt.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
try {
while(in.read(buffer) > -1) {
String asHexStr = DatatypeConverter.printHexBinary(buffer);
if(asHexStr.contains("FB100000010F0801")) {
lastIdArrivalTime = System.currentTimeMillis();
if(!urlSent) {
// send the URL notifying the ID
urlSent = true; // next time url will not be sent
}
}
}
} catch (IOException ex) {
// Log the exception here
}
}
}
private void scheduleTimer() {
timer = new Timer("Timeout");
TimerTask task = new TimerTask() {
#Override
public void run() {
long currentTime = System.currentTimeMillis();
if((currentTime - lastIdArrivalTime) >= timeTolerance) {
// sent the URL notifying the device is off
urlSent = false; // this way the next ID arrival will be notified
}
}
};
timer.scheduleAtFixedRate(task, timeoutInMillis, timeoutInMillis);
}
Some notes:
The timer is scheduled just once this time because it will execute the task every 5 minutes. If you need to shut down the connection don't forget to call timer.cancel() method.
The variable lastIdArrivalTime holds the last time in milliseconds when an ID arrives.
The variable timeTolerance is a max time tolerance to assume the connection is down. As you've said the device sends the ID at a seconds fixed period, so if spent 1 minute since the last ID arrival then you can assume the connection is down (or device is off).
Some hints on your code available here:
TimerTask implements Runnable interface and is intended to be used using Timer class which will create a separate thread to execute this task when the scheduled time comes, so don't use TimerTask in a new thread.
Don't mess with
Threads
unless you know exactly what are you doing. It's extremely easy make a
mistake and mess the things up.

what to use for automatic signout of an App after 30 min in android

I want my application to Automatically signout after 30 minutes.so i am confused with lots of option i have.
1.handlers
but i think if i use handler it won't calculate the display sleep time and i can also not able to resume the handler in another activity.
2.AlarmManager
I dont know much about it but i think it use more cpu memory.
3.CountDownManager like how i used below
new CountDownTimer(40000, 1000) { //40000 milli seconds is total time, 1000 milli seconds is time interval
public void onTick(long millisUntilFinished) {
}
public void onFinish() {
}
}.start();
but can i resume CountDownManager process in another activity
4.timer in java
it will create another thread
or is that nessesary that i should use service and include one of the above methods.because there are possibility that user can press home button and the app goes to onPause() state.or the display can sleep after some time.i also dont want my app to slow down .will using service will slow down my app.can anyone help me.
You can use a timeout, here is a simple example.
public static final int TIMEOUT_FOR_APPLICATION = 1800000;//exit app after 30 minutes
private void timeout() {
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
finish();//or whatever you want to do
}
}, TIMEOUT_FOR_APPLICATION);
}
Hope this is what are you looking for...
Cheers
Add a field lastLogin in your class User.
private static final Long EXPIRE_TIME = 1000L * 60 * 30; //30M
private static final Long DELAY_TIME = 1000L * 60 * 5;
ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(1);
scheduledExecutorService.scheduleWithFixedDelay(new ContainerCleaner(), EXPIRE_TIME, DELAY_TIME, TimeUnit.MILLISECONDS);
public class ContainerCleaner implements Runnable {
#Override
public void run() {
UserCache.cleanupContainer();
}
}
in UserCache
public synchronized void cleanupContainer() {
Collection<User> users= userCache.values();
for (Userp : users) {
if (isExpired(p)) {
expire(p);
}
}
}
private boolean isExpired(SessionProfile sessionProfile) {
if (sessionProfile == null) {
return false;
}
Long lastAccess = sessionProfile.getValue(Name.LASTACCESS);
return System.currentTimeMillis() - lastAccess > EXPIRE_TIME;
}
The code is from my webservice. It will detect if user isExpired every 5 mins.
use AlaramManager and set alarm after 30 minute. and you have to use pending intent for that so your service will be called after 30 minute. and you can do code there.
You can see How to set alarm programetically?
and if you wants to get idle time than if your gets touch or focus than you can reset that alarm.
and for screen off you can write code at onPause and onResume.

Dynamic parameters for #Schedule method in an EJB 3.x

I'm new to the #Schedule annotations in J2EE6
I want to run a job using EJB 3.x with Glassfish 3.1.
The javax.ejb.Schedule seems to be a good choice for us, so we could think of our custom time as something like:
#Singleton
public class CustomTimer {
#EJB
SettingsFacade settingsFacade;
#Schedule(second="someSecondParameter", minute="someMinuteParameter",hour="someHourParameter", persistent=false)
public void executeTimer(){
//Code executing something against database using the settingsFacade
}
}
Here, we want the parameters to be got from database, so they are changed every month. Any clean solution for this?
#Singleton
#Startup
public class ScheduleTimerService {
#Resource private TimerService timerService;
public void setTimerService(TimerService timerService) {this.timerService = timerService; }
#PostConstruct
private void postConstruct() {
timerService.createCalendarTimer(createSchedule());
}
#Timeout
public void timerTimeout(Timer timer) {
Add your code here to be called when scheduling is reached...
in this example: 01h:30m every day ;-)
}
private ScheduleExpression createSchedule(){
ScheduleExpression expression = new ScheduleExpression();
expression.dayOfWeek("Sun,Mon,Tue,Wed,Thu,Fri,Sat");
expression.hour("01");
expression.minute("30");
return expression;
}
}
No, there is no solution with #Schedule, because annotation attributes in general should be compile time constants.
When more flexibility is needed, programmatic timers can be used.
Also then polling database for changed configuration and removing existing and creating new timers must be implemented.
Well You need to created Two Scheduler
One Scheduler will run to update data from Database
Based On that You Can created Other Scheduler.
But for this Need to do it some what programmatic.
You also can see EJB Timers for the same what will help you in this case. which is also annotation based.
There is a simple way of doing this. I wanted to something that called a process every day but, the job itself should be done randomly over the same day. I managed to do that by adding a simple thread worker to run after the EJB timer service has been called. Then I would put it to sleep for a random amount of time during that day.
The following code is an example of a service that wakes up every 1 minute and waits for a thread to finish.
#Schedule(minute = "*/1", hour = "*", persistent = false)
public void runEveryMinute() throws InterruptedException {
log.log(Level.INFO, "Scheduling for every minute .. now it's: " + new Date().toString());
// Delay, in milliseconds before we interrupt adding a follower thread
//we can therefore garantee that it runs every day
long patience = 1000 * 5;
threadMessage("Starting forever alone no more thread");
long startTime = System.currentTimeMillis();
Thread t = new Thread(new MessageLoop());
t.start();
threadMessage("Waiting for new thread to finish");
// loop until MessageLoop thread exits
while (t.isAlive()) {
threadMessage("Still waiting...");
// Wait maximum of 1 second for MessageLoop thread to finish.
t.join(1000);
if (((System.currentTimeMillis() - startTime) > patience)
&& t.isAlive()) {
threadMessage("Tired of waiting! Adding new followers now!");
t.interrupt();
// Shouldn't be long now -- wait indefinitely
t.join();
}
}
threadMessage("Finally! You are not alone anymore!");
}
// Display a message, preceded by
// the name of the current thread
static void threadMessage(String message) {
String threadName = Thread.currentThread().getName();
System.out.format("%s: %s%n", threadName, message);
}
private static class MessageLoop implements Runnable {
public void run() {
String importantInfo[] = {
"A kid will eat ivy too"
};
try {
for (int i = 0;
i < importantInfo.length;
i++) {
// Pause for 4 seconds
int max = 10;
int min = 2;
int randomTimer = 0 + (int) (Math.random() * ((max - min) + 1));
Thread.sleep(randomTimer * 1000);
// Print a message
threadMessage(importantInfo[i]);
}
} catch (InterruptedException e) {
threadMessage("Patience is not a virtue! Thread stopping for now!");
}
}
}

Categories

Resources