I am developing an app on React where countdown timers are the main component (at the same time there can be 10-20 timers on the page). From the server I get: how long the timer should go and how much is left in seconds. Then every second I recount how much is left. The source data is stored in redux, and calculated in the component local state.
These timers should show the same values for every user.
The problem is when I duplicate the tabs in the browser, the api request does not occur, respectively, the timers in a new tab are rolled back to the old state.
Updating data every second in redux seems to me not to be the best option, but I don’t see others yet.
You said that the server sends you the remaining time in seconds. So you can calculate on the client side when the countdown should end in client time. You can store that in local storage. When a new tab is opened you can use that value to initialize your timer.
It does not require the client time to be correct or in sync with the server time as all tabs share the same (possibly wrong) client time. You are only interested in the difference in seconds between the current client time and the client time you saved to correctly initialize your timer.
A solution to calculate it could roughly look like this:
// when receiving the remaining seconds in the first tab
const onReceivedRemaining = (remaining) => {
const now = new Date(); // current client time
now.setSeconds(now.getSeconds() + remaining); // timer end in client time
localStorage.set('elapsing', JSON.stringify(now));
}
// when initializing the timer in a second tab
const getInitial = () => {
const elapsing_string = localStorage.get('elapsing');
if (!elapsing_string) return null;
const now = new Date();
const elapsing = Date.parse(elapsing_string);
return (elapsing - now) / 1000; // remaining time in seconds
}
Related
We are reading from Kinesis and writing to parquet and we use StateSpec<ValueState<Boolean>> to avoid duplicated processing of records after gracefully stopping and relaunching our pipeline from the last savepoint.
We saw that some records were duplicated because they end up falling on a different task manager on subsequent relaunches, and we use StateSpec<ValueState<Boolean>> to store stateful information about the processed records and avoid duplicates.
We are dealing with how to clear the state every certain time without the risk of losing the most recent processed records if they are needed in an upcoming stop. (i.e, we need a something like a TTL on that class).
We thought about a timer that clears the state every certain time but that doesn't meet our requirements because we need to keep the most recent processed records.
We read here that using event time processing automatically clears State information after a window expires and we would like to know if that fits with our requirement using the StateSpec class.
Otherwise, is there a class to store state that has a kind of TTL to implement this feature?
What we have right now is this piece of code that checks if the element has already processed and a method that clears the state every certain time
#StateId("keyPreserved")
private final StateSpec<ValueState<Boolean>> keyPreserved = StateSpecs.value(BooleanCoder.of());
#TimerId("resetStateTimer")
private final TimerSpec resetStateTimer = TimerSpecs.timer(TimeDomain.PROCESSING_TIME);
public void processElement(ProcessContext context,
#TimerId("resetStateTimer") Timer resetStateTimer,
#StateId("keyPreserved") ValueState<Boolean> keyPreservedState) {
if (!firstNonNull(keyPreservedState.read(), false)) {
T message = context.element().getValue();
//Process element here
keyPreservedState.write(true);
}
}
#OnTimer("resetStateTimer")
public void onResetStateTimer(OnTimerContext context,
#StateId("keyPreserved") ValueState<Boolean> keyPreservedState) {
keyPreservedState.clear();
}
Setting the timer every time we call keyPreservedState.write(true); was enough. When the timer expires keyPreservedState.clear(); only clears the element in the contexts, not the whole state.
I have an Angular 6 application that performs an API call every 10 seconds to update price quotes. The timing of the API calls is manages using RxJS interval().
For some reason, on MS Edge, the timings vary wildly, from a couple of seconds, to minutes. Any ideas what might be the cause?
Here is the code:
const refreshPriceInterval = interval(10000);
let startTime = new Date(), endTime: Date;
refreshPriceInterval.pipe(
startWith(0),
flatMap(() => {
endTime = new Date();
let timeDiff = endTime.getTime() - startTime.getTime(); //in ms
// strip the ms
timeDiff /= 1000;
console.log(timeDiff);
startTime = new Date();
return this.timeseriesService.getQuote(symbol, this.userInfo.apiLanguage);
})
)
Here is the console output:
0.001
18.143
4.111
11.057
13.633
12.895
3.003
12.394
7.336
31.616
20.221
10.461
Is there a way to increase the accuracy?
EDIT:
Performance degrades over time.
Reducing the code in the interval() to only a console.log does not perform any better.
Might be an Angular issue.
It is up to the browser to decide how many CPU cycles are allocated per browser tab. Depending on resources (for instance; battery) or activity (background tab vs foreground tab) your browser page will receive more or less cpu slices.
some background: https://github.com/WICG/interventions/issues/5
This is shipped in Edge as well now (as of EdgeHTML14). The clamping to 1Hz in background tabs, not anything more intensive.
Apart from this fact; you are measuring the latency of your call as well:
timeseriesService.getQuote() so it might also be that this call just takes some time.
It was indeed an Angular issue. Timed processes cause Angular to constantly re-render the app, which can be quite resource intensive.
I used runOutsideAngular() to circumvent this issue. It turned out that I only had to run one function outside of Angular:
this.ngZone.runOutsideAngular(() => {
this.handleMouseEvents();
});
Thanks to Mark van Straten for your input!
I want to store data in database in every minute . For the same what should I use Service, AsyncTask or anything else. I go through various link which made me more confused .
I read the developer guide and came to know about getWritableDatabase
Database upgrade may take a long time, you should not call this method from the application main thread,
Then first I think I will use AsyncTask then about this
AsyncTasks should ideally be used for short operations (a few seconds at the most.)
After that I think I can use Service then about Service
A Service is not a thread. It is not a means itself to do work off of the main thread (to avoid Application Not Responding errors).
Here I am not able to understand what should I use to store data in database periodically. Please help me here as struck badly.
Thanks in advance
you cant do a lot work on the UI thread, so making database operations you could choose different approaches, few of them that I prefer to use are listed below;
Create a thread pool and execute each database operation via a thread, this reduces load on UI thread, also it never initializes lot of threads.
You can use services for updating the database operations. since services running on UI thread you cant write your operations in Services, so that you have to create a separate thread inside service method. or you can use Intent service directly since it is not working on UI Thread.
here is developer documentation on thread pool in android
and this is the documentation for IntentService
UPDATE
This will send an intent to your service every minute without using any processor time in your activity in between
Intent myIntent = new Intent(context, MyServiceReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, myIntent, 0);
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 60); // first time
long frequency= 60 * 1000; // in ms
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), frequency, pendingIntent);
Before that check if you really need a service to be started in each minute. or if you can have one service which checks for the data changes in each minute, starting new service would consume maybe more resources than checking itself.
UPDATE 2
private ping() {
// periodic action here.
scheduleNext();
}
private scheduleNext() {
mHandler.postDelayed(new Runnable() {
public void run() { ping(); }
}, 60000);
}
int onStartCommand(Intent intent, int x, int y) {
mHandler = new android.os.Handler();
ping();
return STICKY;
}
this is a simple example like that you can do
Is there a way to run a task in rust, a thread at best, at a specific time or in an interval again and again?
So that I can run my function every 5 minutes or every day at 12 o'clock.
In Java there is the TimerTask, so I'm searching for something like that.
You can use Timer::periodic to create a channel that gets sent a message at regular intervals, e.g.
use std::old_io::Timer;
let mut timer = Timer::new().unwrap();
let ticks = timer.periodic(Duration::minutes(5));
for _ in ticks.iter() {
your_function();
}
Receiver::iter blocks, waiting for the next message, and those messages are 5 minutes apart, so the body of the for loop is run at those regular intervals. NB. this will use a whole thread for that single function, but I believe one can generalise to any fixed number of functions with different intervals by creating multiple timer channels and using select! to work out which function should execute next.
I'm fairly sure that running every day at a specified time, correctly, isn't possible with the current standard library. E.g. using a simple Timer::periodic(Duration::days(1)) won't handle the system clock changing, e.g. when the user moves timezones, or goes in/out of daylight savings.
For the latest Rust nightly-version:
use std::old_io::Timer;
use std::time::Duration;
let mut timer1 = Timer::new().unwrap();
let mut timer2 = Timer::new().unwrap();
let tick1 = timer1.periodic(Duration::seconds(1));
let tick2 = timer2.periodic(Duration::seconds(3));
loop {
select! {
_ = tick1.recv() => do_something1(),
_ = tick2.recv() => do_something2()
}
}
Hey everyone so I have an array private var aFishArray:Array; that is setup with the timer inside my constructor.
tFishTimer = new Timer(800);
//Listen for timer intervals/ticks
tFishTimer.addEventListener(TimerEvent.TIMER, addMainFish,false,0,true);
//Start timer object
tFishTimer.start();
then in the end game Condition I removed the timers tFishTimer.removeEventListener(TimerEvent.TIMER, addMainFish);
tFishTimer.stop();
Now this works perfectly but the problem is when I make a new timer of the same instance inside a separate function like so
private function checkFishPowerHitBucket():void
{
for (var j:int = 0; j < aFishPowerUpArray.length; j++)
{
//get current fish in j loop
var currentfPower:mcMoreFishPowerUp = aFishPowerUpArray[j];
//test if current fish is hitting bucket
if (currentfPower.hitTestObject(bucket))
{
//If we want timer to only run a certain amount of times then new Timer(1000, ??)
tFishTimer = new Timer(100, 30);
//Listen for timer intervals/ticks
tFishTimer.addEventListener(TimerEvent.TIMER, addMainFish, false, 0, true);
//Start timer object
tFishTimer.start();
}
}
}
and then in my end game condition try to remove the timer and the movie clips from entering the screen anymore it no longer happens. The fish just keep appearing on the screen. Is there anything that i can do to remove all instances of these timers when the game is over. Im thinking that by creating a new timer with the same array it cancels the command to delete it when it starts a new timer? any help would be appreciated thanks.
also here is the addMainFish(); Function
private function addMainFish(e:Event):void
{
//Create new fish object
var newFish = new mcMainFish();
//Add fish object to stage
stage.addChild(newFish);
//Add fish to fish Array
aFishArray.push(newFish);
//trace(aFishArray.length);
}
It doesn't really 'delete' the old timer, but what has happened is that when you create the new timer and store it in the same variable, you've lost the reference to the old one, so it just resides somewhere in memory, forever running (or until it hits it's limit, if it has one).
A way to solve this particular problem is to keep a reference to the old timer(s) such as in an array, then when you make a new timer, move the old one to an Timer array first so that you have access to it still.
I do not recommend this.
Having multiple timers like this will cost you in performance and possibly a fair amount of unpredictability. Also, it can lead to some tough debugging down the road as you may have trouble tracing which timer caused which thing to fail, strange instances of objects trying to access the same data, having to deal with so many objects in itself, etc.
What you could do is just have a single dedicated timer and within that timer do All of the processing on each of your objects that need it. You could also avoid a timer altogether and just use your game loop to do this logic.
This post illustrates a similar problem and the answer there is similar to what I've mentioned here.