Introduction

In certain scenarios long running code within the K2 Server may cause remoting timeouts when executed.  The timeout occurs due to the code extenders disconnecting from the .NET remoting pool within 5 minutes of start-up.  This is the default behavior for .NET remoting. 

Note :  After applying this hotfix, the user will be able to set the remoting lifetime for objects created in EXTERNAL applications but all and any code executing within the K2 Server will have an infinite lifetime lease (and will be disposed when done) because of the Extenders that are re-used within K2 Server.

Error Scenario

Note: The circumstances described in this article are one scenario under which this issue may, or is known to occur. The description is intended to be specific to the scenario described and does not take into account all possible scenarios or circumstances.

Use the following code to reproduce the timeout in a Server Event. Sleep the thread for 6 minutes (also in the code) and the error occurs. 

K2.ProcessInstance.DataFields["verndata"].Value = "Testing";
            
            System.Runtime.Remoting.Lifetime.ILease myLease = GetLease(K2.ProcessInstance);
            Console.WriteLine("\n\n THE TIME IS : \n\n" + System.DateTime.Now.ToLongTimeString());
            Console.WriteLine("Initial Lease time is: " + myLease.InitialLeaseTime);
            Console.WriteLine("Current Lease time is: " + myLease.CurrentLeaseTime);
            Console.WriteLine("Renewal on call time time is: " + myLease.RenewOnCallTime);
            Console.WriteLine("Sponsorship timeout is: " + myLease.SponsorshipTimeout);
            Console.WriteLine("Current lease state is: " + myLease.CurrentState.ToString());
 
            RenewObject((MarshalByRefObject) K2.GetServerContext());
            RenewObject(K2.ActivityInstanceDestination);
            RenewObject(K2.ProcessInstance);
            myLease = GetLease(K2.ProcessInstance);
            Console.WriteLine("\n\n THE TIME IS : " + System.DateTime.Now.ToLongTimeString());
            Console.WriteLine("Initial Lease time is: " + myLease.InitialLeaseTime);
            Console.WriteLine("Current Lease time is: " + myLease.CurrentLeaseTime);
            Console.WriteLine("Renewal on call time time is: " + myLease.RenewOnCallTime);
            Console.WriteLine("Sponsorship timeout is: " + myLease.SponsorshipTimeout);
            Console.WriteLine("Current lease state is: " + myLease.CurrentState.ToString());
            System.Threading.Thread.Sleep(1000 * 60 * 6);
        }
        public System.Runtime.Remoting.Lifetime.ILease GetLease(System.MarshalByRefObject obj)
        {
            return (System.Runtime.Remoting.Lifetime.ILease)obj.GetLifetimeService();
        }
        public void RenewObject(MarshalByRefObject obj)
        {
            System.Runtime.Remoting.Lifetime.ILease lease =
                    (System.Runtime.Remoting.Lifetime.ILease)System.Runtime.Remoting.RemotingServices.
                        GetLifetimeService(obj);
            lease.Renew(TimeSpan.FromMinutes(30));
        }
    }
}


 

Error Message

Object has been disconnected or does not exist at the server.

Error Resolution

This Hotfix is contained within the latest K2 Update. Install the update package to resolve the error.

To make the remoting pool stay active for longer than the default .NET time of 5 minutes, change the setting <Remoting Enable="false" />  to “true” in the K2Server.setup file and ensure that the following appears in the K2HostServer.config file with the relevant values specified for each item:

<system.runtime.remoting>
                <application>
                                <lifetime
                                         leaseTime="10M"
                                         sponsorshipTimeout="10M"
                                         renewOnCallTime="10M"
                                         leaseManagerPollTime="10S"
                                />
                </application>
</system.runtime.remoting>

Internally, all classes in K2Server (ProcessInstance, ActivityInstanceDestination, DataField, XmlField, Lines etc.) will use these values to determine how long the objects should stay active in memory once they are not being used anymore but have not been disposed / deleted as of yet.  So if the timeout values in the K2HostServer.config file are set to 10 minutes, and somewhere in the server code, a ProcessInstance object is created yet never disposed, it will stay in memory for 10 minutes before it will be disconnected from the .NET pool and be collected.  If no values are added to the config, the default of .NET applies which is 5 minutes.