I had developed a Java based Lotus Domino Email Client Application. I am saving the lotus.domino.Session object in httpsession.setAttribute for session management.we decided to deploy the application on two different servers and manage load balancing and Session Replication between the two.
Now we are facing issues while Replicating lotus.domino.Session because lotus.domino.Session is not serialized.
Kindly help me
Thanks
AFAIK, you are out of luck.
Domino objects (that is, anything in the lotus.domino package) store a link to a C API object that must be garbage collected to avoid memory leaks.
As a result, if a Domino object is serialized, it will become toxic at the end of the request in which it was stored, because its C object link will have been automatically recycled at the end of that request.
As Leyrer says, it is not possible to serialise any Domino Object as it has a C-API backend component to it which cannot be stored.
Also the Session object was never designed for connection pooling either. So even if you skip the serialisation, you may encounter other issues.
Depending on what it is you are trying to accomplish, you could create your own serialisable object with just the references you need to recreate the session and any other objects.
Related
I have a WCF service handling a very large number of requests (thousands per second). Each request contains objects, so they get built inside the DataContractSerializer during deserialization. My service processes the messages, and they get cleaned up by the .net garbage collector.
The problem is that garbage collections are causing problems for my service (requests occasionally taking 100+ milliseconds longer than they should). I need to minimize them. So I am looking for a way of using object pooling. In other words, I want the data contract serializer to obtain an object from my object pool (instead of getting one via GetUninitializedObject), and then when I am done processing the message, I would release it back to the pool for cleaning & reuse, thereby avoiding thousands of memory allocations a second.
I've seen this is possible with protobuf-net (Using protobuf-net, is it possible to deserialize a message without allocating memory?) and in fact I'm using protobuf elsewhere, but for this particular situation that is not an option
The DataContractSerializer is sealed and cannot be updated. So unfortunately you would not be able to remove it's call to FormatterServices.GetUninitializedObject.
What you will have to do instead is create your own serializer inheriting from XmlObjectSerializer so that you can fully control instance creation.
The next step is to create a DataContractSerializerOperationBehavior and override the CreateSerializer methods to return your customized serializer.
Last thing to do is remove the default DataContractSerializerOperationBehavior from the endpoint and replace it with the custom one that implements your custom serializer. Carlos Figueira has a post on his blog showing exactly how to do this (go to the section called Real world scenario: using a new serializer).
In my app, I have this scenario where I need to post an object to remoter server and get an object key back and then store the object locally. I have Core data and Restkit implemented in my app.
The object value are collected from user input. I couldn't figure out a great way to prepare the object before posting it to remote server. This object is an entity of type NSManagedObject, and I don't want to store it before I get the object id from server.
I came across this which suggested to use a transient object to handle this situation. But as discussed in that thread, this causes issue with code maintenance.
Is there a better way to handle this scenario? Thanks.
Make your core data model class adhere to the RKRequestSerializable protocol.
Then when the user input is validated, create an entity as normal and set it as the params value to the RKRequest, this will send your object as the HTTP body. Look inside RKParams.m for an example.
Also set the newly created entity as the targetObject for the RKObjectLoader. That way, when your web service returns the information (like the new unique ID), it will target the new object and save the new unique ID to this object without creating a duplicate.
Clear as mud?
PS: Oh and be careful mixing autogenerated core data classes with custom code! I recommend mogen to help you not lose code each time you make a change.
I have a WCF service application (actually, it uses WCF Web API preview 5) that intercepts each request and extracts several header values passed from the client. The idea is that the 'interceptor' will extract these values and setup a ClientContext object that is then globally available within the application for the duration of the request. The server is stateless, so the context is per-call.
My problem is that the application uses IoC (Unity) for dependency injection so there is no use of singleton's, etc. Any class that needs to use the context receives it via DI.
So, how do I 'dynamically' create a new context object for each request and make sure that it is used by the container for the duration of that request? I also need to be sure that it is completely thread-safe in that each request is truly using the correct instance.
UPDATE
So I realize as I look into the suggestions below that part of my problem is encapsulation. The idea is that the interface used for the context (IClientContext) contains only read-only properties so that the rest of the application code doesn't have the ability to make changes. (And in a team development environment, if the code allows it, someone will inevitably do it.)
As a result, in my message handler that intercepts the request, I can get an instance of the type implementing the interface from the container but I can't make use of it. I still want to only expose a read-only interface to all other code but need a way to set the property values. Any ideas?
I'm considering implementing two interfaces, one that provides read-only access and one that allows me to initialize the instance. Or casting the resolved object to a type that allows me to set the values. Unfortunately, this isn't fool-proof either but unless someone has a better idea, it might be the best I can do.
Read Andrew Oakley's Blog on WCF specific lifetime managers. He creates a UnityOperationContextLifetimeManager:
we came up with the idea to build a Unity lifetime manager tied to
WCF's OperationContext. That way, our container objects would live
only for the lifetime of the request...
Configure your context class with that lifetime manager and then just resolve it. It should give you an "operation singleton".
Sounds like you need a Unity LifetimeManager. See this SO question or this MSDN article.
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.
I have been working on splitting up the app tier and web tier of a web application. In the app tier, I managed to separate the business logic into a bunch of services exposed using WCF proxies. The problem is that these services talk to another legacy application that uses a large CLR object as its primary means of communication. To keep things quick, I had been keeping a copy of this object in the session after I created it the first time. Now I know that WCF can do sessions, but the session storage is per service whereas my business logic is now split into multiple services (as it should be).
Now the questions:
Is there a way to share session storage between WCF services hosted on the same host?
Is this even something I should be doing?
If not, then what are the best practices here?
This is probably not the first time somebody’s had a large business object on the server. Unfortunately for me, I really do need to cache this object per user (hence the session).
It’s possible the answer is obvious and I'm just not seeing it. Help please!
I think instance context sharing can help
http://msdn.microsoft.com/en-us/library/aa354514.aspx
As far as I understand WCF, it is designed to be as stateless as it could be. In a session you can remember some values in your service, but objects are not meant to live outside the scope of a session.
Therefore, I'd think you are in trouble.
Of course, there might be some way to store and exchange objects between sessions that I don't know (I use WCF, but I don't know very much about it, apart from what I need for myself).
(if there is a way to share objects between services, it probably would only work on services you host yourself. IIS hosting might recycle your service sometimes)
Perhaps you can wrap this object in a singleton service. This is a service with only one instance, which will not be destroyed between calls. Because you need an object for each user, this service has to manage a list of them and the calling services has to provide the needed authentication data (or sessionid). Don't forget a timeout to get rid of unneeded objects...
Create a facade service which hosts the large CLR object on behalf of the other app tier services. It can work as an adapter, allowing more specific session identifiers to the more advanced app tier services you have created. The facade can provide a session identifier, like a GUID, which your app tier services can use to get re-connected with the large CLR object.
This provides a few advantages:
Some of your app tier might not need to know about the CLR object at all. They only communicate with the remote facade.
the 'large CLR object' host retains the session object on behalf of the other services who can now share it.
The app tiers now have a facade through which they talk to the legacy service. As you work to refactor this legacy service, the app tier doesn't have to change.
Depending on your setup, you may be able to host the facade via in proc hosting which will give retain performance boost you are seeking.
Breaking things up into subservices seems like a good idea if you want to be able to spread the app out over a farm. However, it's important to keep in mind that whenever an object crosses the appdomain boundary at the vary least it will have to be copied in memory.
It all depends on how big the object is and what kind of data it holds.
If you don't want to pass the object because it's too large you may want to make a query API for the service which receives it. In this way you could manipulate that object without having to do expensive serialization or remoting.
Keep it simple. Since you already have access to Session in your WCF, you can use the SessionID from there. Now:
Create a static dictionary somewhere, where the Key is your sessionId and the value is the business object you want to store.
Instead of accessing the business object in session, just access the sessionid and get the business object from the Value of your dictionary.
(You can also use some type of caching if you wish, for example System.Web.Caching, that way you don't have to cleanup the dictionary manually)