How to set sliding expiration for HashSet using ConnectionMultiplexer of StackExchange.Redis lib - stackexchange.redis

We are storing a list of properties in the Hash Set as shown in the following code
HashEntry[] snippetProepries = {
new HashEntry("properties", JsonSerializer.Serialize(propertyModelList)),
new HashEntry("created_at", DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss"))
};
redisCache.HashSet(claimsSnippetId, snippetProepries);
There is an option to set the Expiration using redisCache.KeyExpire(claimsSnippetId, TimeSpan.FromHours(24));, but it seems it's of absolute type.
How I can set Sliding expiration for the HashSet in my case?
Thanks,
Saurabh

Related

How to set TTL for Couchbase document dynamically for every save operation using springframework CrudRepository?

I want to set different TTL value on every save operation of particular document. Like I have one document containing employee and designation fields.
For every new employee, based on designation value TTL should be set accordingly. Like if employee is Solution Architect then document expiry should be set for 30 Days. If designation is "Senior Architect" then expiry should be set as 20 Days.
I know how to set expiry through spring Framework, but how to set it dynamically? PFB:
#Document(expiry = Constants.COUCHBASE_RESOURCE_TTL)
public class EmployeeResource {
}
You can touch the document just after saving it and set the TTL defined by a variable.
Let's say that you have a method called getTTLByEmployee which will return the TTL (int) by Employee type. You can do something like:
Employee savedEmployee = yourRepository.save(employee);
yourRepository.getCouchbaseOperations().getCouchbaseBucket()
.touch(savedEmployee.getId(), getTTLByEmployee(employee.getEmployeeType()));
You can use http://docs.couchbase.com/sdk-api/couchbase-java-client-2.2.4/com/couchbase/client/java/Bucket.html#touch-java.lang.String-int- method to extend/renew the TTL for the document at runtime, in addition to the default setting.

Dynamics 365 implementation auto number with plugin

I have already implement auto number with plugin, and it is through another entity type to ensure all operations are in one transaction.
but I have another question, that is can we use process lock(eg. mutex) to fix it? this will more flexible than before, isn't it?
Dynamics 365 has native support for auto-numbering fields since v9.0, with the minor inconvenience of having to manipulate them through code only.
Unless it's a broken feature (it happens), there's no need for custom autonumbers anymore.
https://learn.microsoft.com/en-us/dynamics365/customer-engagement/developer/create-auto-number-attributes
Example:
CreateAttributeRequest widgetSerialNumberAttributeRequest = new CreateAttributeRequest
{
EntityName = "newWidget",
Attribute = new StringAttributeMetadata
{
//Define the format of the attribute
AutoNumberFormat = "WID-{SEQNUM:5}-{RANDSTRING:6}-{DATETIMEUTC:yyyyMMddhhmmss}",
LogicalName = "new_serialnumber",
SchemaName = "new_SerialNumber",
RequiredLevel = new AttributeRequiredLevelManagedProperty(AttributeRequiredLevel.None),
MaxLength = 100, // The MaxLength defined for the string attribute must be greater than the length of the AutoNumberFormat value, that is, it should be able to fit in the generated value.
DisplayName = new Label("Serial Number", 1033),
Description = new Label("Serial Number of the widget.", 1033)
}
};
_serviceProxy.Execute(widgetSerialNumberAttributeRequest);
Docs point out that
The sequential segment is generated by SQL and hence uniqueness is guaranteed by SQL.
XrmToolbox should have a plugin to manage auto number fields (thus making it easier), but I haven't tried it.
Plugin's can be run on multiple machines concurrently depending on your installation - that's why the entity (database) lock is regularly used.

How to search by element value in the list of Redis cache?

We are using the redis cache and below the sample type of data we are storing
LLPUSH mylist "abc" "xyx" "awe" "wwqw"
Now I am want to search in the redis from Spring project. For example my Spring project class receives one element from some external client "abc". How can search the Redis list by value? Something like below:
ListOperations<String, Object> listOperations = redisTemplate.opsForList();
listOperations.get(key,"abc"); // returns abc
Or at least I want confirmation that this element is present in the list of Redis cache:
listOperations.contains(key, "abc"); // returns either true or false, based on the value presence
Can someone please suggest of this type of client lib is present for Redis from Java side and that we can use in the Spring boot project?
Redis lists are implemented as linked lists.
Hence, you will either have to get all elements of the list using LRANGE and iterate to find a particular element.
If the list does not contain multiple entries and the order is not
relevant, we can use LREM to remove the particular element and if
there is a difference in list size, the element exists. Later, the
removed element can be re-inserted if exists.
Long initialSize = redisTemplate.opsForList().size(key);
redisTemplate.opsForList().remove(key,0, value);
Long finalSize = redisTemplate.opsForList().size(key);
if(finalSize - initialSize > 0){
redisTemplate.opsForList().rightPush(key,value);
return true; //Element exists
}
return false; //Does not exist
Consider making the operations atomic.
You can get the other spring redis list operations from here.
You can use Redis Set which has sismember(keyForSet,valueToSearch) to search element by value with O(1) complexity which is efficient, In order to use with redisTemplate you can use redisTemplate.opsForSet.isMember(keyForSet,valueToSearch)
While inserting you can insert list like
jedis.sadd(keyForSet, myList.toArray(new String[myList.size()]));
Or with redisTemplate redisTemplate.opsForSet.add(keyForSet, myList.toArray(new String[myList.size()]));
You can easily do this with Redisson Redis client and Redis based List object:
List<String> list = redisson.getList("myList");
list.add("aaa");
list.add("bbb");
list.add("ccc");
// returns true
list.contains("aaa");

How to use Cache.getOrElse(java.lang.String key, java.util.concurrent.Callable<T> block, int expiration)

How to use Cache.getOrElse(java.lang.String key, java.util.concurrent.Callable block, int expiration)
Could someone give me a example?
My point is how to use “expiration",I know it means expire time.
By the way:
I want save some object to cache,and set a expire time.
when the expire time,I can reset the object to the cache.
Thanks.
Let's assume that, you want to set User object on cache, for that you set userId as key and user object as value. If need set expiration time, for sample i set it as 30secs.
cache.set(userId, userObject, 30);
At some point of time, if you want to get user object from cache, which you set earlier using userId as key, you might try the following way to get the user object from cache.
User user = cache.get(userId);
Above will return you the user object, if you access within 30secs, otherwise it will return NULL. This will be perfect for case like validating the session.
In some case, you frequently need to retrieve value from cache, for that following is the best approach.
User user = cache.getOrElse(userId, () -> User.get(userId), 30);
cache will check, whether it has given userId as key, if available then straight away return the user object and update the expiration time to 30secs further.
If given userId not available, then callable block gets invoked and set userId as key, user object fetched from db as value and expiration time as 30secs.
Expiration is the number of seconds that the Object would be hold in the Cache. If you pass 0 as expiration the Cache doesn't expire and you would have to control it by hand.
What getOrElse does is check the Cache, if the Object is not there then call the callable block that you are passing and adds the result to the cache for the number of seconds that you are passing as expiration time.
I based my comment in the Play Framework Cache Javadoc.
I use getOrElse in controllers when I have dynamic and static content to display. Cache the static and then render it together with the dynamic part:
try {
Html staticHtml = Cache.getOrElse("static-content", () -> staticView.render(), 60 * 60);
Html rendered = dynamicPage.render(arg1, arg2, staticHtml);
return ok(rendered);
} catch (Exception e) {
e.printStackTrace();
return internalServerError();
}
staticView.render() returns some html from a view. This view should not call any other pages which are dynamic or you stash something you do not really want to stash.
60*60 means I want to store it for one hour (60 seconds times 60 minutes... ok you can write 3600 if you want)
I should add that getOrElse gets the Object from the cache with the specified key (in this example the key is static-content) but if it cannot find it, then it calls the function which returns an object which is then stored for the specified amount of time in the cache with that key. Pretty neat.
Then you can call some other (dynamic) page and pass the html to it.
The dynamic stuff will stay dynamic :)

Emit mapper Ignoring member at mapping time

I am using Emit mapper to copy values from one object to the other.
When I am mapping the objects, I need to ignore certain fields from being mapped/copied over. The fields to be ignored keeps changing based on scenario.
How can this be done in EmitMapper? The .Map method itself does not take any additional parameters to ignore certain properties. I can specify fields to be ignored using DefaultMapConfig, but that is static and cannot be changed during mapping.
Please help.
You have to configure the Mapper:
string[] fieldsToIgnore = { "NameOfThePropertyToIgnore" };
var mapper = ObjectMapperManager.DefaultInstance
.GetMapper<SourceClass, DestClass>(
new DefaultMapConfig()
.IgnoreMembers<SourceClass, DestClass>(fieldsToIgnore)
);

Resources