Can Redis be used as a self populating cache (or pull-through cache) ?
In other words, is it able to create an entry on the fly if this entry is not cached yet ?
Redis is just a store: you add things to it and retrieve them back again. It has no awareness of what you are using it for (caching) or knowledge of the backend it would perform lookups from, that will depend on the application handling the request and using Redis to cache.
Can Redis be used as a self-populating cache (or pull-through cache)?
Yes! But Redis doesn't have an implementation for self-population.
So you just have to implement it yourself and it's easy too.
Define a wrapper class that extends(is-a relation) a redis client(of your choice).
Define Factory interfaces to create objects.
Override necessary methods that require pull-through implementation
3.1 If the key already exists, return it.
3.2 Otherwise use factory interfaces to create the value, cache it and return it.
Hope this answer is generic enough for any redis client.
Related
The page on Service Discovery using apache curator (https://github.com/Netflix/curator/wiki/Service-Discovery) introduces the following concepts:
The main abstraction class is ServiceProvider. It encapsulates the discovery service for a particular named service along with a provider strategy. A provider strategy is a scheme for selecting one instance from a set of instances for a given service. There are three bundled strategies: Round Robin, Random and Sticky (always selects the same one). ServiceProviders are allocated by using a ServiceProviderBuilder.
Each of the above query methods calls ZooKeeper directly. If you need more than occasional querying of services you can use the ServiceCache. It caches in memory the list of instances for a particular service. It uses a Watcher to keep the list up to date. You allocate a ServiceCache via the builder returned by ServiceDiscovery.serviceCacheBuilder().
I can see how to use the Provider strategies with a ServiceProviderBuilder, but there's no equivalent method on the ServiceCacheBuilder, and the only relevant method available on the ServiceCache class itself is getInstances(), which gets all instances.
How can I use a provider strategy with a ServiceCache?
#simonalexander2005 I was just looking in the code and it turns out that ServiceProvider internally already uses a serviceCacheBuilder. TBH - I've either forgotten about this or it got put in by another committer - I'm not sure. Anyway, I'm very sorry about the runaround here. Also, the documentation must be updated to reflect this - I'll open an issue for this today. I'm sure this be maddening to you, again sorry for this. The good news, though, is that with ServiceProvider you automatically get caching.
Frankly, the docs on this are really bad. It would be fantastic if someone could give a pull request with better docs...
Notice that ServiceCache implements InstanceProvider. Also notice that ProviderStrategy.getInstance() has as its argument InstanceProvider. Therefore, you can pass a ServiceCache instance to whichever ProviderStrategy you want to use.
I hope this helps.
I wonder what is the best way to manage NHibernate Session Context
when using NH data layer from Xsockets controller.
Particularly I refer to self hosted winservice/console application or Azure worker role,
where HTTPContext is not available.
Of course there is always an option to create and dispose session per call, but that means a performance hit, so better reuse sessions in some way.
My controller provides API for CRUD operations in underlying NH repository and is pushing updates to relevant subscribers when certain records are updated in DB.
Your ideas appreciated :)
I'm using StructureMap to handle dependencies and create a NestedContainer to handle session per request. Don't have to mess with CurrentSessionContext or HttpContext anymore for storing session.
http://structuremap.github.io/the-container/nested-containers/
You could even just create a middleware UnitOfWork if you are using OWIN with WebAPI.
Since XSockets has state is will be bad for your database if you open the connection in the OnOpen event since the connection will remain open as long as the socket is open. Best is to use the repository only in the methods calling the CRUD operations as briefly as possible.
To get the instance of your repository should not be a bottleneck in this case.
I will be happy to review any code you might have.
Regards
Uffe
Ok so I have an n tiered model. (WPF, Asp.Net, etc) to backend services via WCF. These services use NHibernate to communicate with the database. Some of these services will be run in InstanceContextMode.Single mode.
Questions:
In singleton service instances should I try to utilize 1 session object for the entire time the wcf service is alive to get the most out of my cache?
If I use 1 session instance in this singleton instance and never create new ones I assume I have to worry about eventually removing cached entities from the session or dumping it all together to avoid performance issues with the session?
Is it a good idea at all to use the session in this way for a singleton wcf service? It seems like it would be if I want to utilize caching.
Should I utilize 2nd level cache in a scenario like this?
Outside of this scenario when should I avoid caching? I would assume that I would want to avoid it in any sort of batching scenario where a large number of objects are created/updated and never really used again outside of the creation or updates.
Are items automatically cached in session when I create/read/update/delete or do I need to specify something in the mapping files or configuration?
1-3: As far as I know, ISession objects are supposed to be light-weight, short-lived objects, which live only for the duration for which they're needed. I would advise AGAINST using the same ISession object for the whole lifetime of your service.
What I would suggest instead is using the same ISeessionFactory instance, and creating new ISessions from it as necessary (you can try something similar to Session-Per-Request pattern).
If you enable 2nd level cache, you can have all the benefits of caching in this scenario.
5 Yep, pretty much. Also remember that 2nd level cache instance is per ISessionFactory instance. that means that if you're using more than 1 ISessionFactory instance you'll have a lot of problems with your cache.
6 for 1st level cache you don't need to define anything.
for 2nd level cache you need to enable the cache when you configure nHibernate (fluently, in my case):
.Cache(c => c.UseQueryCache()
.ProviderClass(
isWeb ? typeof(NHibernate.Caches.SysCache2.SysCacheProvider).AssemblyQualifiedName //in web environment- use sysCache2
: typeof(NHibernate.Cache.HashtableCacheProvider).AssemblyQualifiedName //in dev environmet- use stupid cache
))
)
and specify for each entity and each collection that you want to enable cache for them:
mapping.Cache.ReadWrite().Region("myRegion");
and for a collection:
mapping.HasMany(x => x.Something)
.Cache.ReadWrite().Region("myRegion");
I am building a web application, and whenever I make a database call I need a session.
I understand creating a session object is very expensive.
I am following the repository pattern here: http://web.archive.org/web/20110503184234/http://blogs.hibernatingrhinos.com/nhibernate/archive/2008/10/08/the-repository-pattern.aspx
He uses something called a UnitOfWork to get the session.
For a web application, shouldn't I be storing the Session in Request.Items collection? So its only created once per request?
Do I really need UofW?
The session IS the unit of work - its basically used to store changes until you flush them to the db. Save a static session factory at startup, and use that to create one session per web request - Request.Items seems a valid place to put the session.
The repository pattern is a wrapper over the unit of work. The repository pattern differs from the UoW pattern in that repo.Save(obj) should save the obj to the db straight away, while the UoW waits for a flush.
My advice would be to skip the repository pattern and use the ISession directly (see http://ayende.com/Blog/archive/2009/04/17/repository-is-the-new-singleton.aspx)
In the case of NHibernate the key class is the SessionFactory, which SessionProvider is taking care of for you (if you implement it like that). Keep the SessionFactory alive, and it handles the sessions for you.
I've also seem people save the SessionFactory in their IoC.
Use this to manage your sessions:
HybridSessionBuilder
It manages and gives you access to a single session that's used across the entire application.
I know that the session is used for the database in Hibernate, but what is the task of the session in database?
Does anyone know about this?
Update:
Apologies, my links are to Java APIs (must have missed the nhibernate tag). Regardless, there will be more than one type of session for .NET also.
There will typically be more than one type of session:
The HttpSession is a server-side object:
Provides a way to identify a user
across more than one page request or
visit to a Web site and to store
information about that user.
The hibernate Session is also a server-side object:
The lifecycle of a Session is bounded
by the beginning and end of a logical
transaction. (Long transactions might
span several database transactions.)
The main function of the Session is to
offer create, read and delete
operations for instances of mapped
entity classes.
The session is server side, if by server side you mean as in the web application or client/server application sense.
It is an implementation of the Unit of Work pattern, and does stuff like keeping track of which entities that have been changed, caching of entities and making sure that a specific entity is represented by only one actual instance in the scope of the session.
The NHibernate docs describe ISession like this:
A single-threaded, short-lived object
representing a conversation between
the application and the persistent
store. Wraps an ADO.NET connection.
Factory for ITransaction. Holds a
mandatory (first-level) cache of
persistent objects, used when
navigating the object graph or looking
up objects by identifier.