I'm building an app where I need to have three scoreboards which I'm implementing with sorted sets and lists. The app is running on node.js using the node_redis (https://github.com/mranney/node_redis) module for the redis client.
The first scoreboard is a 'latest scores' which I'm using a list and LPUSH for. The second is an all time high score which I'm using a sorted list for with the ZADD command.
I'm having trouble implementing a 'high scores this week'. I was thinking that I should use another sorted list using ZADD with an EXPIRE set for one week. That all works fine, but after the list has expired for the first time, it'll continue to add to a new list forever.
Is there a redis command to have an expire to auto renew? (I've been searching for an answer for a couple of hours now but the answer appears to be no). I'm coming to the conclusion that I'll need to do this programmatically. During a function call that uses the set, I could check to see if the TTL is -1 and reset it there and then. Is this best practice? Am I missing a clever trick somewhere? Do I need to be concerned about the extra database requests?
--EDIT--
I've had a reply to this question on twitter https://twitter.com/redsmin/status/302177241167691777
The suggested solution (if I understand correctly) is to use the EXPIREAT command along with each ZADD
expireat myscoreboard {{timestamp of the end of the week}}
zadd myscoreboard 1 "one"
This "feels" right to me but I'm new to redis so would appreciate some discussion on this technique or any other ways of solving the problem.
It depends on how you define "one week". There are several ways to use it, for example:
"The last 7 days"
"Week of the year"
"This week starting on sunday and ending on Saturday"
The simplest to implement are 2 & 3.
You specify a set which includes in it's keyname the date/time to start on, using an expire of one week. You then simply determine on the client side which day you want and grab the data.
For example
zadd scoreboard:weekly:03:March:2013 1 "bob"
Then the following week your keyname would be
zadd scoreboard:weekly:10:March:2013 1 "bob"
When you first create the key you set the expires, and that is all. No need to re-set it every time. Pseudocode follows:
if (ttl scoreboard:weekly:03:March:2013) == 0:
expire scoreboard:weekly:03:March:2013 604800
This way you only set the expiration once, get auto-expiration, and can easily pull the weekly scoreboard.
You could implement a rolling week using the same method but you would need to go to a daily key name and calculate what keys to get, then merge them. You could do this using zunionstore.
Related
I created a mongo db server on my local machine and a database and within a row we are targeting just one field "count" with default value of 0.
Node_instance1 - node server having an increase_api to hit a url which targets a row's one field "count".
and INCREASES(+) the "count" +100 times.
Node_instance1 - node server having an decrease_api to hit a url which targets a row's one field "count".
and DECREASES(-) the "count" -100 times.
Now every time we hit the both the apis once...
one server increases the count while another server decreases the "count" and finally out database "count" value should be "0" at the end and we do receive 0 atleast everytime i tried.
but if i increase the repeat ion from 100 to 1000 the value at the end is not "0" it's any random integer. i tried many times and almost every time i get different random number and not "0".
i thought mongo is an ACID compliant database. i am not really sure where is the problem or what might be going wrong. any comments are welcome to point me in the right direction.
I JUST WANT TO KNOW IF WE CAN USE ONE DATABASE WITH MULTIPLE APPLICATION SERVERS OR I GUESS MY QUESTION IF WE SHOULD. i am newbie. so thank you very much for any help! Appreciated!.
I want to create a mechanism for a password reset using Node JS and firebase. The user's profile is stored in firebase auth.
My aim: from the GUI, a user request for a password reset email. A user can request for reset password a maximum of 3 times within 1 hour. If still, he doesn't get reset email then he can request again after 1 hour.
I thought about several options to do this, but not sure which one is better for good performance and security. From my point of view, I need to store two values: request number and request time. I thought about below ways to do this:
Create a document in the firestore to maintain these two values.
Use customClaims of the firebase auth user to maintain these two values.
Use client-side cookies to request numbers and use customClaims to store request time.
I thought using the 1st and 2nd option will lead to several firebase operations. Which end up charging me unnecessarily more cost for read/write operations. And the 3rd option will create a loophole.
Can you suggest a better option or which option should I choose from the above for implementing the reset password mechanism which avoids multiple requests from the same user for a periodic time?
Thank you.
You can try storing the number of password resets in firebase database or even keep a history of that. When user requests to change password, check his last reset and if-else statement will do rest of the job.
For example let's say I'm an user of your app and reset the password now, then you store current time in your database and update number of resets in last 1 hour.
You will have to fetch this information when I am about to change password again.
So when I click password reset button, fetch this information.
Store the time in the form of timestamp. Means timestamp now is around 1588570404. Get the timestamp at the moment when reset button is pressed and use if-else.
if(timeDifference <= 3600) {
//deny resetting as time since last reset is less than an hour
}
else {
//reset password
}
1 hour comprises of 3600 seconds so the difference should be greater than 3600 seconds.
You can add additional conditions to check how many times the user has changed password within last hour as mentioned above the code.
But you will need to reset that count after every hours so good luck with that. Maybe your can reset it when you perform checks for last reset.
I'm trying to make a expire key system with nodejs to one app and for check expiration (30 days) I decided use a while loop and checking it, but as I thought, I need another thread to do this, I tried use the worker_thread but gives me "Module did not self-register" at "node_modules\Canvas\lib\bindings.js:3:18". There is a way to do this process or still another way to do the keys expire? I'm new to node and I don't have any other ideia.
Obs:. to check if a key is expired, it store the time in millis that the key was got and store another value with the time in millis 30 days after, and do a simple (expireTime - gotTime <= 0)
I have a question regarding the Python API of Interactive Brokers.
Can multiple asset and stock contracts be passed into reqMktData() function and obtain the last prices? (I can set the snapshots = TRUE in reqMktData to get the last price. You can assume that I have subscribed to the appropriate data services.)
To put things in perspective, this is what I am trying to do:
1) Call reqMktData, get last prices for multiple assets.
2) Feed the data into my prediction engine, and do something
3) Go to step 1.
When I contacted Interactive Brokers, they said:
"Only one contract can be passed to reqMktData() at one time, so there is no bulk request feature in requesting real time data."
Obviously one way to get around this is to do a loop but this is too slow. Another way to do this is through multithreading but this is a lot of work plus I can't afford the extra expense of a new computer. I am not interested in either one.
Any suggestions?
You can only specify 1 contract in each reqMktData call. There is no choice but to use a loop of some type. The speed shouldn't be an issue as you can make up to 50 requests per second, maybe even more for snapshots.
The speed issue could be that you want too much data (> 50/s) or you're using an old version of the IB python api, check in connection.py for lock.acquire, I've deleted all of them. Also, if there has been no trade for >10 seconds, IB will wait for a trade before sending a snapshot. Test with active symbols.
However, what you should do is request live streaming data by setting snapshot to false and just keep track of the last price in the stream. You can stream up to 100 tickers with the default minimums. You keep them separate by using unique ticker ids.
In my node application with mongodb I have feature where users can post books on rent and other users can request for them with a "whenDate". One post is mapped to only one book.
Consider a user requests for a book for 1 week 5 days from now. In this case I want to lock the book for a week so that no one else can request at that period.
1) How can I achieve in NodeJs that a function gets executed after sometime considering that I will be having many of them? This function will get executed after 5 days in the above case to lock the particular book document. Please consider the question 2 also.
2) I don't want these timers to get deleted if I restart my application. How can I achieve this?
Thanks in advance.
You can use TTL feature in mongo DB to discard records automatically after the time to live.
Let's say you keep a table with the booking requests and set TTL according to the booking duration. Mongo DB then can remove these booking record after the TTL is achieved. So your node.js application does not need to trigger any job.
Refer: https://docs.mongodb.com/manual/tutorial/expire-data/