Transactional Create with Validation in ServiceStack Redis Client - redis

User has DisplayName and it is unique for Users.
I want to Create User but firstly I have to check display name (DisplayName could not be duplicated for Users)
I've checked ServiceStack examples and I could not see Transactional Insert/Update with validation check.
How can I perform it. I dont want to write "Validation Tasks" for redis db.
I dont want inconsistency in db.

The ServiceStack.Redis client does have support for Redis's WATCH and transactions where these Redis commands:
WATCH mykey
test = EXIST mykey
MULTI
SET mykey $val
EXEC
Can be accomplished with:
var redis = new RedisClient();
redis.Watch("mykey");
if (!redis.ContainsKey("mykey")) return;
using (var trans = redis.CreateTransaction()) {
trans.QueueCommand(r => r.Set("mykey", "val"));
trans.Commit();
}

Is possible to perform redis transactions. More information here
WATCH mykey
test = EXIST mykey
MULTI
SET mykey $val
EXEC
Using PHP have um better example: here

Related

Redis Keyspace Notifications subscription for field&value

i'm currently working about Redis Expire Event
My goal : get the Value, Field to do something in next process after Data in Redis already expire
so i had found Redis Keyspace Notifications Feature
That Allow client to Subscribe to Channel in Redis to Recieve Event affecting Data in reset like Expire
so i have some example code : https://github.com/toygame/nodejs-redis-keyspace-notifications
subscriber.subscribe("__keyevent#0__:expired")
subscriber.on('message', async(channel, message) => {
// do somethings
console.log(message);
})
Result : Key0
And this work find but the Result i got is only Key that i have set into redis and expired
I have already do some research
https://medium.com/nerd-for-tech/redis-getting-notified-when-a-key-is-expired-or-changed-ca3e1f1c7f0a
but its found only Event that maybe i can get as result but not for Value, Field that i expect
is their anyway to get Those Value and Field ?
FYI. Document https://redis.io/topics/notifications
UPDATE
according to this https://stackoverflow.com/a/42556450/11349357
Keyspace notifications do not report the value, only the key's name and/or command performed are included in the published message.The main underlaying reasoning for this is that Redis values can become quite large.
If you really really really need this kind of behavior, well that's pretty easy actually. Because keyspace notifications are using Pub/Sub messages, you can just call PUBLISH yourself after each relevant operation, and with the information that you're interested in.
look like i can't use this Redis Keyspace but i have to publish its on my own
You can use RedisGears to process keyspace notification and get both key and value.
You can write your processing code in python and register it in Redis.
e.g. Capture each keyspace event and store to a Stream
GearsBuilder() \
.foreach(lambda x: execute('XADD', "notifications-stream", '*', *sum([[k,v] for k,v in x.items()],[]))) \
.register(prefix="person:*", eventTypes=['hset', 'hmset'], mode='sync')
You can read more about this example here: https://oss.redis.com/redisgears/examples.html#reliable-keyspace-notification

How Spring store cache and key to Redis

I follow some tutorial on web to setup Spring Cache with redis,
my function look like this:
#Cacheable(value = "post-single", key = "#id", unless = "#result.shares < 500")
#GetMapping("/{id}")
public Post getPostByID(#PathVariable String id) throws PostNotFoundException {
log.info("get post with id {}", id);
return postService.getPostByID(id);
}
As I understand, the value inside #Cacheable is the cache name and key is the cache key inside that cache name. I also know Redis is an in-memory key/value store. But now I'm confused about how Spring will store cache name to Redis because looks like Redis only manages key and value, not cache name.
Looking for anyone who can explain to me.
Thanks in advance
Spring uses cache name as the key prefix when storing your data. For example, when you call your endpoint with id=1 you will see in Redis this key
post-single::1
You can customize the prefix format through CacheKeyPrefix class.

Using RPUSH with TTL in a single command in Redis

I'm trying to push an entry in a list in Redis and also want to update the TTL of the list every time a new entry comes in. I can do that my simple calling the EXPIRE "my-list" ttl using Redis. Since my application is receiving heavy traffic, I want to reduce the number of calls to redis.
Can I set my TTL during the push operation in Redis, i.e RPUSH "mylist" I1 I2...IN ex "TTL", does redis support this time of command functionality. I can see that it does support this for the String data structures.
Redis does not have dedicated commands to push and expire the List, although as you've mentioned it does have something like that for the String data type.
The way you'd go about this challenge is to compose your own "command" from existing ones. Instead of having your application call these commands, however, you would use a Lua script as explained in the EVAL documentation page.
Lua scripts are cached and run atomically on the server. One such as the following would probably help in your case - it expects to get the key name, the pushed element and the expiry value:
local reply = redis.call('RPUSH', KEYS[1], ARGV[1])
redis.call('EXPIRE', KEYS[1], ARGV[2])
return reply

Share redis storage between multiple apps

I am using redis in a node application for caching data and now i want to access and modify stored data using a django application on the same server but i can't access to the data.
Django connection:
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/0",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
using keys * command in terminal:
$ redis-cli
127.0.0.1:6379> keys *
1) "sess:Ok0eYOko5WaV7njfX04qgqG1oYe0xiL1" -> this key is set in node
2) ":1:from-django" -> this key is set in django
Accessing keys in django application:
keys = cache.keys('*')
print(keys) # prints only one key => ['from-django']
I can't access first key that is set in node application and also django stored keys are prifixed with :1: by default!
I want to share all keys between node and django but they only access their own keys.
Any idea?
You can access all of data from any where, But you are working with Redis in Cache model! and all of Cache systems has own unique data structure, You must work with Redis in Database model and scan it yourself.
Use Python Redis package to access all of Redis in your application.

Clear X key from Hashes

There is 3 Hashes in my redis database:
set:recentbooks
set:badbooks
set:funnybooks
All hashes contain book Ids as key.
I want to remove the book that has 234 Id from all hashes.
How can I do this:
Lua Scripting
Pipeline
Other?
Using the ServiceStack redis client API, you could pipeline your delete requests like thus:
var client = new RedisClient("localhost", 6379);
using (var pipeline = client.CreatePipeline())
{
pipeline.QueueCommand(r => r.RemoveEntryFromHash("set:recentbooks", "234"));
pipeline.QueueCommand(r => r.RemoveEntryFromHash("set:badbooks", "234"));
pipeline.QueueCommand(r => r.RemoveEntryFromHash("set:funnybooks", "234"));
// All deletes will be sent at once.
pipeline.Flush();
}
Using a LUA script, it's easy:
EVAL "redis.call('HDEL',KEYS[2],KEYS[1]);
redis.call('HDEL',KEYS[3],KEYS[1]);
redis.call('HDEL',KEYS[4],KEYS[1]);"
4 234 set:recentbooks set:badbooks set:funnybooks
I've never used ServiceStack, but with the info above you have what's required to invoke the redis client in ServiceStack to delete the keys.
You can also write the lua script in a file, then call it like this with parameters:
redis-cli> EVAL "$(cat myscript.lua)" 4 234 set:recentbooks set:badbooks set:funnybooks