I have this scenario, where data from my sensor is sent to my server every 5 minutes. The server stores received data in the database. Now when a server receives the data, I want to start 6 minutes timer for this specific sensor. If I receive data earlier than those 6 minutes, this timer must be canceled and started again. If the timer happens to finish, onFinish() must be called, which then I will send a notification to the user about a possible connection issue with the sensor. I have this list of sensors and a method that gets called when the server receives data:
// list to save sensors and their timers
private val sensors: MutableMap<Long, CountDownTimer> = HashMap()
// this method gets called after server receives data from the sensor
// must keep in mind that CountDownTimer is undefined
fun initiateTimer(sensorId: Long) {
sensors[sensorId] = object : CountDownTimer(360000, 1000) {
fun onTick(duration: Long) {
// Blank
}
fun onFinish() {
// Send notification to user about possible connection issue
}
}.start()
}
I've been looking into scheduleWithFixedDelay, but this requires ExecutorService with specific threads count. Now what if I have thousands of sensors and I need those thousand timers running at once?
Now in Android, I can simply use CountDownTimer, but since it's not Android, I am seeking advice for the best possible approach to solve this problem using Kotlin in Spring Boot environment (or in simple terms, not in Android environment). Thank you.
ScheduledExecutorService that you found is a standard way of scheduling tasks in the future. You can schedule thousands of timers and execute them all using a single thread - no problem with that.
Alternatively, if you use coroutines, you can use utils like delay() or withTimeout().
Also, if you really plan to have a big number of such timers, then it could be easier to implement and maintain alternative solution where we only have a single "ticking" thread/coroutine that checks all sensors once per e.g. 10 seconds. It iterates over all sensors and checks when the data was received the last time. When new data arrives, we only update the time, but we don't need to cancel and restart any timers.
Related
My app is an Android app for booking tables.so the app directly communicating with the server.I need to call a specific event that is generated by the Android app.say an item is purchased by the Android app, so I need to hold that item for 2 hour so no one can use that item.i'm thinking change the flag inside the database to not available. After the use that is after 2 hour I need to release the item for the other users.
I know from trigger will done the job but is it possible to delete the crown trigger from the table and remove the scheduling.
Why would you hold/release like that? It doesn't seem robust... if there's some kind of communication error, the bike could get hung up permanently. I would run something based off timestamps and calculate the bike's availability in realtime based on the date. These calculations are going to be cheap to do.
If you want to handle this on the client side then you have to do it using AlarmManager, schedule an event to make an api call or just release it locally. But as u said cron job will be a better way to do it where u update the db after 2 hrs.
If you want to run particular Rest API
, after every 2 hr , You can either set Repeating ALARM , or you can user Timer and Timer Task
OR
If you want to just notify the user after 2 hr,
Then you can use cron-trigger with cloud messaging like FCM (firebase clod messaging )
I have a database with datas and my android application when it was launched checks if there is a new record in the database.
I created a Service and it checks every ten seconds if there is a new record and alert me with a notification.
I think it isn't the best solution cause it checks every ten seconds so it use the battery and internet every ten seconds.
Is there another solution to do that without check every ten seconds, for example, by using some code in my php form which add content in my database.
Thanks in advance.
You are right, there is plenty of solutions.
One of powerfull solutions is implementation of publish subscribe pattern.
In short: All subscribed clients will be notified on any change for which they are subscribed.
For quick info and start point use this link: https://developers.google.com/cloud/samples/mbs/pubsub_messaging.
General about publish subscribe: http://docs.oracle.com/cd/E19798-01/821-1841/bnced/index.html
I'm developing an app which must heavily interact with the server.So user input name and password and after authorization the next tasks must be performed:
The app has to fetch all incoming and outcoming messages for this user and load them to SQLite database.
Fetch all user friends (JSON with id,names,contact_data) and also load it to the app's database
Jump to the next activity and display income messages from the local database.
The problem this operations are too slow and when app starts new activity it is nothing to fetch from the database :AsyncTasks have not completed yet.I'm forced to use AsyncTask.get() in order to wait when they all complete but this takes over 16 seconds to wait!So what should I do: use threads, or before loading fetched data to database hold it in memory and display it in the new activity instead of fetching it from the database?But even without database tasks other fetching tasks take nearly 10 seconds to wait!So what should I do?
Oke a couple of things going pretty wrong here.
Do not use AsyncTasks for Networking. Use a service. In short, this is because your AsyncTask will stop, as soon as the Activity that started it will stop. This means that network requests get aborted easily and data goes lost and has to re-start again when the Activity is opened again.
Do not use .get() on AsyncTasks. This makes the UI thread wait for the task to complete, making the whole AsyncTask idea kinda useless. In other words: This blocks your UI.
What you should do:
Read up on using services. You can also have a look at a great opensource library called RoboSpice to help you with this.
Stop using .get() on AsyncTasks, if you want to know when it is done just use a listener.
Execute AsyncTasks on a threadpool ( myTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); ) when possible.
You should use a Service. This way it always can complete the tasks it was doing and you can complete all your tasks. Besides that you should initialize the app once, and after that only update the data.. that can't take 10 seconds.. than you're having an other problem.. But the nice thing of the service is that this can run in the background. see: Services in Android Tutorial
== Edit
Also take a look at GreenDao This library arranges fast SQlLite operations. Without the large setup!
AsyncTasks are not meant to run several small tasks concurrently at the same time. Quoting the docs
When first introduced, AsyncTasks were executed serially on a single background thread. Starting with DONUT, this was changed to a pool of threads allowing multiple tasks to operate in parallel. Starting with HONEYCOMB, tasks are executed on a single thread to avoid common application errors caused by parallel execution.
Use Threads in a ThreadPool when you want to run multiple tasks concurrently.
How you want to handle this situation is up to you. When the background tasks take too long, you can always show an alert dialog to the user and then take them to the activity once the data has been populated. Many apps show a 'Loading' screen when this happens. You can also show the 'Loading' Spinner control if no data is available yet. Never show a blank screen.
If the server side calls are under your control, employ some sort of caching to speed up the time. Any API call that lasts more than a second will make for an impatient user. If not employ one of the techniques mentioned in the previous paragraph. #Perception's technique is also one to consider if you can do it.
I am new to threads. I want to communicate with multiple sensors at one time after every minute continuously 24/7.
Senario:
I have a method to talk to the sensors which takes 3 arguments
public String perform(String command, String ip, String port)
{
//talk to the sensor and then
returns reply;
}
I have a database that contains the details of the sensor.
What I'm doing right now
while(true)
{
//get sensors from database
//run perform method for all instruments
for(int i=0;i<sensors.length-1;i++)
{
//call perform method and save the reply
}
Thread.sleep('one minute');
}
Problem:
The problem is if I have 100 sensors and each sensor takes 1 second to reply then after that I will be waiting for 1 minute, in this case I may lose some information. And to be honest sometime It takes more than a second to respond.
What I want to do is, get the information from the database for all the sensors
then create one thread for each sensor. Then run all the threads at one time which will return me some information. After that wait for one minute then do it again.
Any help is appreciated.
Thanks
Have you looked at the ScheduledThreadPoolExecutor ?
A simple usage would be to create a Callable for each of your sensors, and configure the thread pool to contain as many threads as you have sensors. Then submit each Callable, specifying an appropriate schedule.
Note that this approach doesn't guarantee particularly accurate timings (Java's not by any means a real-time platform). The other issue is that creating a lot of threads can be relatively memory-hungry (IIRC the standard heap allocation per thread is 512k, but it's configurable) and this approach wouldn't scale if you had 1000s of sensors.
Personally I would take a different approach. I would have the server always listening via a RESTful API and then have the sensors POST their state every minute (or other interval you decide). This way the server and the sensors don't need to be within the same JVM and IMHO is more scalable. Also, this way any sensor can also query for the state of any other sensor via another RESTful API on the server.
Additionally the server can start a thread to handle each POST and if one sensor is taking very long, the others are not blocked.
I have a Spring-MVC, Hibernate, (Postgres 9 db) Web app. An admin user can send in a request to process nearly 200,000 records (each record collected from various tables via joins). Such operation is requested on a weekly or monthly basis (OR whenever the data reaches to a limit of around 200,000/100,000 records). On the database end, i am correctly implementing batching.
PROBLEM: Such a long running request holds up the server thread and that causes the the normal users to suffer.
REQUIREMENT: The high response time of this request is not an issue. Whats required is not make other users suffer because of this time consuming process.
MY SOLUTION:
Implementing threadpool using Spring taskExecutor abstraction. So i can initialize my threadpool with say 5 or 6 threads and break the 200,000 records into smaller chunks say of size 1000 each. I can queue in these chunks. To further allow the normal users to have a faster db access, maybe I can make every runnable thread sleep for 2 or 3 secs.
Advantages of this approach i see is: Instead of executing a huge db interacting request in one go, we have a asynchronous design spanning over a larger time. Thus behaving like multiple normal user requests.
Can some experienced people please give their opinion on this?
I have also read about implementing the same beahviour with a Message Oriented Middleware like JMS/AMQP OR Quartz Scheduling. But frankly speaking, i think internally they are also gonna do the same thing i.e making a thread pool and queueing in the jobs. So why not go with the Spring taskexecutors instead of adding a completely new infrastructure in my web app just for this feature?
Please share your views on this and let me know if there is other better ways to do this?
Once again: the time to completely process all the records in not a concern, whats required is that normal users accessing the web app during that time should not suffer in any way.
You can parallelize the tasks and wait for all of them to finish before returning the call. For this, you want to use ExecutorCompletionService which is available in Java standard since 5.0
In short, you use your container's service locator to create an instance of ExecutorCompletionService
ExecutorCompletionService<List<MyResult>> queue = new ExecutorCompletionService<List<MyResult>>(executor);
// do this in a loop
queue.submit(aCallable);
//after looping
queue.take().get(); //take will block till all threads finish
If you do not want to wait then, you can process the jobs in the background without blocking the current thread but then you will need some mechanism to inform the client when the job has finished. That can be through JMS or if you have an ajax client then, it can poll for updates.
Quartz also has a job scheduling mechanism but, Java provides a standard way.
EDIT:
I might have misunderstood the question. If you do not want a faster response but rather you want to throttle the CPU, use this approach
You can make an inner class like this PollingThread where batches containing java.util.UUID for each job and the number of PollingThreads are defined in the outer class. This will keep going forever and can be tuned to keep your CPUs free to handle other requests
class PollingThread implements Runnable {
#SuppressWarnings("unchecked")
public void run(){
Thread.currentThread().setName("MyPollingThread");
while (!Thread.interrupted()) {
try {
synchronized (incomingList) {
if (incomingList.size() == 0) {
// incoming is empty, wait for some time
} else {
//clear the original
list = (LinkedHashSet<UUID>)
incomingList.clone();
incomingList.clear();
}
}
if (list != null && list.size() > 0) {
processJobs(list);
}
// Sleep for some time
try {
Thread.sleep(seconds * 1000);
} catch (InterruptedException e) {
//ignore
}
} catch (Throwable e) {
//ignore
}
}
}
}
Huge-db-operations are usually triggered at wee hours, where user traffic is pretty less. (Say something like 1 Am to 2 Am.. ) Once you find that out, you can simply schedule a job to run at that time. Quartz can come in handy here, with time based triggers. (Note: Manually triggering a job is also possible.)
The processed result could now be stored in different table(s). (I'll refer to it as result tables) Later when a user wants this result, the db operations would be against these result tables which have minimal records and hardly any joins would be involved.
instead of adding a completely new infrastructure in my web app just for this feature?
Quartz.jar is ~ 350 kb and adding this dependency shouldn't be a problem. Also note that there's no reason this need to be as a web-app. These few classes that do ETL could be placed in a standalone module.The request from the web-app needs to only fetch from the result tables
All these apart, if you already had a master-slave db model(discuss on that with your dba) then you could do the huge-db operations with the slave-db rather than the master, which normal users would be pointed to.