In a Django app, I use redis to maintain a global sorted set where user ids are stored with the score of current time since epoch.
After every 11 minutes, I am to run an asynchronous task that trims the sorted set to solely values that were saved in the previous 10 minutes, nothing beyond.
Would the following accomplish this? I'm unsure about edge cases (e.g. will this ensure all old values are deleted or will some leak, etc.):
time_now = time.time() #current time since epoch
ten_mins_ago = time_now - (10*60)
eleven_mins_ago = time_now - (11*60)
my_redis_server.zremrangebyscore(sorted_set,eleven_mins_ago,ten_mins_ago)
Replace eleven_mins_ago with the string value -inf to delete everything that's older than 10 minutes and to avoid any "leak"age. Refer to the Exclusive intervals and infinity section of the ZRANGE's documentation page for full details and explanation.
Related
This script shows that the timestamp that redis returns seems to jump forward a lot and then go backwards from time to time. This happens regularly throughout the run, on every run. What's going on? Is this documented anywhere? I stumbled on this as it messes up my sliding window rate limiter.
res_0, res_1 = 0, 0
for _ in range(200):
script = f"""
local time = redis.call("TIME")
local current_time = time[1] .. "." .. time[2]
return current_time
"""
res_0 = res_1
res_1 = float(await redis.eval(script, numkeys=0))
print(res_1 - res_0)
time.sleep(0.01)
1667745169.747809
0.011765003204345703
0.01197195053100586
0.011564016342163086
0.011634111404418945
0.012428998947143555
0.011847972869873047
0.011600971221923828
0.011788129806518555
0.012033939361572266
0.012130022048950195
0.01160883903503418
0.011954069137573242
0.012022972106933594
0.011958122253417969
0.011713981628417969
0.011844873428344727
0.012138128280639648
0.011618852615356445
0.011570215225219727
0.011890888214111328
0.011478900909423828
0.7928261756896973
-0.5926899909973145
0.11812996864318848
0.11584997177124023
0.12353992462158203
0.1199800968170166
0.11719989776611328
0.12331008911132812
-0.8117339611053467
0.011723995208740234
0.01131582260131836
The most likely reason for this behavior is floating point arithmetic on the calling code side: parsing floats would inevitably round (not sure about the extent, since you didn't tell what platform you are coding against) the input value and the original result precision is lost. So, I would suggest to review your logic so that you process the two components of the result returned by TIME independently using a couple of integers / longs instead.
In addition to that, apart from the obvious possibility of an issue with the clock of the Redis server, there may also be the chance you are contacting different Redis hosts along with each iteration - this may hold true in the event you are using a multi-node Redis topology (replication or cluster).
I am looking to add a variable to count from 1 to 217 every hour in AnyLogic, in order to use as a choice condition to set a parameters row reference.
I am assuming I either need to use an event or a state chart however I am really struggling with the exact and cannot find anything online.
If you have any tips please let me know, any help would be appreciated
Thank you,
Tash
A state machine isn't necessary in this case as this can be achieve using a calculation or a timed event. AnyLogic has time() function which returns time since model start as a double in model time units of measurements.
For example: if model time units is seconds and it has been running for 2hr 2min 10sec then time(SECOND) will return 7330.0 (it is always a double value). 1/217th of an hour corresponds to about 3600/217 = 16.58 seconds. Also, java has a handy function Math.floor() which rounds down a double value, so Math.floor(8.37) = 8.0.
Assembling it all together:
// how many full hours have elapsed from the start of the model
double fullHrsFromStart = Math.floor(time(HOUR));
// how many seconds have elapsed in the current model hour
double secondsInCurrentHour = time(SECOND) - fullHrsFromStart * 3600.0;
// how many full 16.58 (1/217th of an hour) intervals have elapsed
int fullIntervals = (int)(secondsInCurrentHour / 16.58);
This can be packaged into a function and called any time and it is pretty fast.
Alternatively: an Event can be created which increments some count by 1 every 16.58 seconds and ten resets it back to 0 when the count reaches 217.
I made an experimentation on Psychopy. I have Intructions, 10 differents routines and then msg end.
I am able to have all the time it took for each routine, but I will like to have the total time of my 10 routines without having to calculate it my self in my csv file at the end.
Code for having my duration of each trial. I putted this line in each routine.
thisExp.addData('trial_duration1', t)
I tried to create a variable total and adding all the trial_duration, but my column was empty in the csv file at the end.
Thanks!!
Psychopy has an internal clock which starts when the experiment starts. You can read the time using core.monotonicClock.getTime(). The timing of this clock starts almost immediately as you hit "run", i.e. before the dialogue box, so it doesn't read the time since the first routine started. However, you can get that duration by first recording the time of the clock in a code component when you want time zero to be defined:
time_zero = core.monotonicClock.getTime()
... and then record the time elapsed doing
thisExp.addData('cumulative_duration', core.monotonicClock.getTime() - time_zero)
Note that if you want to do this only for particular loops (e.g. define time_zero in the first loop and record cumulative_duration in the last loop) require the condition to be satisfied:
# If this is the first iteration of the loop (no matter the name of the loop)
if currentLoop.thisN == 0:
time_zero = core.monotonicClock.getTime()
I'm working on a 2D video game framework, and I've never written a game loop before. Most frameworks I've ever looked in to seem to implement both a draw and update methods.
For my project I implemented a loop that calls these 2 methods. I noticed with other frameworks, these methods don't always get called alternating. Some frameworks will have update run way more than draw does. Also, most of these types of frameworks will run at 60FPS. I figure I'll need some sort of sleep in here.
My question is, what is the best method for implementing this type of loop? Do I call draw then update, or vice versa? In my case, I'm writing a wrapper around SDL2, so maybe that library requires something to be setup in a certain way?
Here's some "pseudo" code I'm thinking of for the implementation.
loop do
clear_screen
draw
update
sleep(16.milliseconds)
break if window_is_closed
end
Though my project is being written in Crystal-Lang, I'm more looking for a general concept that could be applied to any language.
It depends what you want to achieve. Some games prefer the game logic to run more frequently than the frame rate (I believe Source games do this), for some games you may want the game logic to run less frequently (the only example of this I can think of is the servers of some multiplayer games, quite famously Overwatch).
It's important to consider as well that this is a question of resolution, not speed. A game with logic rate 120 and frame rate 60 is not necessarily running at x2 speed, any time critical operations within the game logic should be done relative to the clock*, not the tic rate, or your game will literally go into slow motion if the frames take too long to render.
I would recommend writing a loop like this:
loop do
time_until_update = (update_interval + time_of_last_update) - current_time
time_until_draw = (draw_interval + time_of_last_draw) - current_time
work_done = false
# Update the game if it's been enough time
if time_until_update <= 0
update
time_of_last_update = current_time
work_done = true
end
# Draw the screen if it's been enough time
if time_until_draw <= 0
clear_screen
draw
time_of_last_draw = current_time
work_done = true
end
# Nothing to do, sleep for the smallest period
if work_done == false
smaller = time_until_update
if time_until_draw < smaller
smaller = time_until_draw
end
sleep_for(smaller)
end
# Leave, maybe
break if window_is_closed
end
You don't want to wait for 16ms every frame otherwise you might end up over-waiting if the frame takes a non-trivial amount of time to complete. The work_done variable is so that we know whether or not the intervals we calculated at the start of the loop are still valid, we may have done 5ms of work, which would throw our sleeping completely off so in that scenario we go back around and calculate fresh values.
* You may want to abstractify the clock, using the clock directly can have some weird effects, for example if you save the game and you save the last time you used a magical power as a clock time, it will instantly come off cooldown when you load the save, as that is now minutes, hours or even days in the past. Similar issues exist with the process being suspended by the operating system.
Looking for some ideas on how to implement this, don't necessarily need the exact code.
Let's say I have a game where the player's hit points are displayed in a label, say 100HP. When he takes damage, say 30 damage, I want that label to count down from 99, 98 , 97 ... 70. It should take 2 seconds to perform the countdown whether you take 30 damage or 3000 damage.
I'm wondering what's the most efficient way to get this loop to count down "smoothly" over 2 seconds no matter what the damage taken is.
I'd probably extend a CCLabelSomething to do that, embedding the desired behaviour. Suggest a fixed width font, otherwise nothing smooth will happen (visually). Figure out what is 'smooth for you', ie how many updates in the 2 second period. in the assumed 'setScore' public method, start a scheduled update cycle with appropriate delay. In the schedule callback, change the text of the label.
say 20 updates, ie 10 per seconds. Schedule with .1f delay between intervals. Upon setScore, compute the 'delta' per update (currentScore - newScore)/20. Decrement currentScore down to newScore by this delta. In the schedule callBack, stop your scheduled update if the displayed score is equal to the newScore.