using System; using System.Collections.Generic; using System.Text; namespace IndianHealthService.BMXNet.Services { internal class BMXRemoteSessionPool : RemoteSessionPool { private Log _log = new NullLog(); public Log Log { get { return _log; } set { _log = value; } } public void Begin(BMXNetSessionConnectionSource aSource) { this.Source = aSource; this.AllowAllocation = true; } private bool _allowAllocation = false; public bool AllowAllocation { get { return _allowAllocation; } set { _allowAllocation = value; } } private int _maxSessions = 5; public int MaxSessions { get { return _maxSessions; } set { _maxSessions = value; } } public int IdleSessionCount { get { return this.IdleConnections.Count; } } public int AvailableSessionCount { get { return this.MaxSessions - this.AllocatedSessions.Count; } } private BMXNetSessionConnectionSource _source = null; internal BMXNetSessionConnectionSource Source { get { return _source; } set { _source = value; } } private List _idleConnections = new List(); public List IdleConnections { get { return _idleConnections; } set { _idleConnections = value; } } private List _allocatedSessions = new List(); public List AllocatedSessions { get { return _allocatedSessions; } set { _allocatedSessions = value; } } #region RemoteSessionPool Members public bool HasAvailableSession { get { return this.AvailableSessionCount > 0; } } public RemoteSession OpenSession() { return this.OpenSession(this.Log); } public RemoteSession OpenSession(Log aLog) { if (this.HasAvailableSession && this.AllowAllocation) { BMXNetRemoteSession session = new BMXNetRemoteSession(); session.Log = aLog; if (this.IdleConnections.Count > 0) { this.Log.Log("BMX NET", "Debug", "Open Idle Session "); session.IsPrimary = (this.IdleSessionCount + this.AllocatedSessions.Count) == 1; this.AllocatedSessions.Add(session); BMXNetSessionConnection connection = this.IdleConnections[0]; connection.ReceiveTimeout = 0; connection.SendTimeout = 0; this.IdleConnections.Remove(connection); session.Begin(connection, this); } else { this.Log.Log("BMX NET", "Debug", "Open New Session "); session.IsPrimary = (this.IdleSessionCount + this.AllocatedSessions.Count) == 0; this.AllocatedSessions.Add(session); session.Begin(this.Source.OpenConnection(), this); } if (!session.IsPrimary) { session.PrimarySession(this.PrimarySession); } return (RemoteSession)session; } else { this.Log.Log("BMX NET", "Info", "No Session Available"); return null; } } private BMXNetRemoteSession PrimarySession { get { foreach (BMXNetRemoteSession each in this.AllocatedSessions) { if (each.IsPrimary) { return each; } } return null; } } private void ReleaseSession(RemoteSession aSession) { BMXNetRemoteSession bmxSession = aSession as BMXNetRemoteSession; if (bmxSession.IsPrimary) { this.Close(); } else { bmxSession.Suspend(this); this.AllocatedSessions.Remove(bmxSession); this.IdleConnections.Add(bmxSession.SessionConnection); } } public void CloseSession(RemoteSession aSession) { if (aSession.IsPrimary) { this.TerminateAll(); } else { this.ReleaseSession(aSession); } } public void Close() { this.AllowAllocation = false; foreach (BMXNetRemoteSession each in new List(this.AllocatedSessions)) { each.IsPrimary = false; this.ReleaseSession(each); } this.TerminateAll(); } #endregion public void CloseAll() { List toClose = new List(this.AllocatedSessions); this.AllocatedSessions = new List(); foreach (BMXNetRemoteSession each in toClose) { this.CloseSession(each); } } private void TerminateAll() { this.AllowAllocation = false; this.CloseAll(); this.TerminateIdleSessions(); } /// /// Note: idle session connections are really being terminated. We /// do not re-use BMXNetRemoteSession objects that wrap the session connection /// public void TerminateIdleSessions() { List toTerminate = new List(this.IdleConnections); this.IdleConnections = new List(); foreach (BMXNetSessionConnection each in toTerminate) { this.TerminateConnection(each); } } private void TerminateConnection(BMXNetSessionConnection aConnection) { this.Source.CloseConnection(aConnection); } } }