public void BvtDurableCase3() { Info("Start BVT"); SessionStartInfo sessionStartInfo; sessionStartInfo = BuildSessionStartInfo(Server, EchoSvcName, null, null, null, null, SessionUnitType.Node, null, null, null); sessionStartInfo.Secure = false; sessionStartInfo.ShareSession = true; Info("Begin to create session"); string serviceJobId; int clientNum = 2; AutoResetEvent anotherClient = new AutoResetEvent(false); using (DurableSession session = DurableSession.CreateSession(sessionStartInfo)) { serviceJobId = session.Id; var epr = new EndpointAddress(string.Format(NetTcpEndpointPattern, Server, serviceJobId)); Info("EPR: {0}", epr); Task[] tasks = new Task[clientNum]; for (int i = 0; i < clientNum; i++) { var idx = i; tasks[i] = Task.Run( () => { string guid = Guid.NewGuid().ToString(); try { Info("Client {0}: Begin to send requests.", guid); using (BrokerClient <IEchoSvc> client = new BrokerClient <IEchoSvc>(guid, session)) { for (int j = 0; j < NumberOfCalls; j++) { client.SendRequest <EchoRequest>(new EchoRequest(j.ToString()), j + ":" + guid); } Info("Client {0}: Begin to call EndOfMessage.", guid); client.EndRequests(); Info("Client {0}: Begin to get responses.", guid); int count = 0; if (idx == 0) { foreach (BrokerResponse <EchoResponse> response in client.GetResponses <EchoResponse>()) { count++; Info(response.Result.EchoResult); string[] rtn = response.Result.EchoResult.Split(new[] { ':' }); Assert( rtn[rtn.Length - 1] == response.GetUserData <string>().Split(new[] { ':' })[0] && response.GetUserData <string>().Split(new[] { ':' })[1] == guid, "Result is corrupt: expected:computername:{0}, actual:{1}", response.GetUserData <string>().Split(new[] { ':' })[0], response.Result.EchoResult); } } else { foreach (var response in client.GetResponses()) { count++; EchoResponse result = (EchoResponse)response.Result; Info(result.EchoResult); string[] rtn = result.EchoResult.Split(new[] { ':' }); Assert( rtn[rtn.Length - 1] == response.GetUserData <string>().Split(new[] { ':' })[0] && response.GetUserData <string>().Split(new[] { ':' })[1] == guid, "Result is corrupt: expected:computername:{0}, actual:{1}", response.GetUserData <string>(), result.EchoResult); } } if (count == NumberOfCalls) { Info("Client {0}: Total {1} calls returned.", guid, count); } else { Error("Client {0}: Total {1} calls returned, but losing {2} results.", guid, count, NumberOfCalls - count); } } } catch (Exception e) { Error("Unexpected exception of Client {0}", e.ToString()); throw; } finally { if (Interlocked.Decrement(ref clientNum) <= 0) { anotherClient.Set(); } } }); } anotherClient.WaitOne(); Task.WaitAll(tasks); session.Close(true); session.Dispose(); } }
static void Main(string[] args) { //change the headnode name here const string headnode = "[headnode]"; const string serviceName = "EchoService"; const int numRequests = 12; SessionStartInfo startInfo = new SessionStartInfo(headnode, serviceName); startInfo.BrokerSettings.SessionIdleTimeout = 15 * 60 * 1000; startInfo.BrokerSettings.ClientIdleTimeout = 15 * 60 * 1000; Console.Write("Creating a session for EchoService..."); // Create a durable session int sessionId = 0; DurableSession session = null; bool successFlag = false; int retryCount = 0; const int retryCountMax = 20; const int retryIntervalMs = 5000; while (!successFlag && retryCount++ < retryCountMax) { try { session = DurableSession.CreateSession(startInfo); successFlag = true; } catch (EndpointNotFoundException e) { Console.WriteLine("EndpointNotFoundException {0}", e.ToString()); } catch (CommunicationException e) { Console.WriteLine("CommunicationException {0}", e.ToString()); } catch (TimeoutException e) { Console.WriteLine("TimeoutException {0}", e.ToString()); } catch (SessionException e) { Console.WriteLine("SessionException {0}, error code 0x{1:x}", e.ToString(), e.ErrorCode); // if session fatal errors happen, no retry if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.SessionFatalError)) { Console.WriteLine("SessionExceptionCategory : SessionFatalError {0}", e.ToString()); Console.WriteLine("No retry."); retryCount = retryCountMax; continue; } } catch (Exception e) { Console.WriteLine("General exception {0}", e.ToString()); } if (!successFlag) { Console.WriteLine("=== Sleep {0} ms to retry. Retry count left {1}. ===", retryIntervalMs, retryCountMax - retryCount); Thread.Sleep(retryIntervalMs); } } if (!successFlag) { Console.WriteLine("Create durable session failed."); return; } sessionId = session.Id; Console.WriteLine("Done session id = {0}", sessionId); //send requests successFlag = false; retryCount = 0; const int sendTimeoutMs = 5000; const int clientPurgeTimeoutMs = 60000; while (!successFlag && retryCount++ < retryCountMax) { using (BrokerClient <IService1> client = new BrokerClient <IService1>(session)) { Console.Write("Sending {0} requests...", numRequests); try { for (int i = 0; i < numRequests; i++) { //client.SendRequest<EchoFaultRequest>(new EchoFaultRequest("dividebyzeroexception"), i, sendTimeoutMs); client.SendRequest <EchoDelayRequest>(new EchoDelayRequest(5000), i, sendTimeoutMs); } client.EndRequests(); successFlag = true; Console.WriteLine("done"); } catch (TimeoutException e) { // Timeout exceptions Console.WriteLine("TimeoutException {0}", e.ToString()); } catch (CommunicationException e) { //CommunicationException Console.WriteLine("CommunicationException {0}", e.ToString()); } catch (SessionException e) { Console.WriteLine("SessionException {0}, error code 0x{1:x}", e.ToString(), e.ErrorCode); if (SOAFaultCode.Broker_BrokerUnavailable == e.ErrorCode) { Console.WriteLine("SessionException : BrokerUnavailable {0}", e.ToString()); } // Session Exceptions are unrecoverable unless they are application errors if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.ApplicationError)) { Console.WriteLine("SessionExceptionCategory : ApplicationError {0}", e.ToString()); } // if session fatal errors happen, no retry if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.SessionFatalError)) { Console.WriteLine("SessionExceptionCategory : SessionFatalError {0}", e.ToString()); Console.WriteLine("No retry."); retryCount = retryCountMax; continue; } } catch (Exception e) { //general exceptions Console.WriteLine("Exception {0}", e.ToString()); } //purge client if not succeeded, needed? if (!successFlag) { try { client.Close(true, clientPurgeTimeoutMs); } catch (Exception e) { Console.WriteLine("Failed to purge the client after send request failure {0}", e.ToString()); } } } if (!successFlag) { Console.WriteLine("=== Sleep {0} ms to retry. Retry count left {1}. ===", retryIntervalMs, retryCountMax - retryCount); Thread.Sleep(retryIntervalMs); } } if (!successFlag) { Console.WriteLine("Send requests failed."); return; } //dispose the session here session.Dispose(); //attach the session SessionAttachInfo attachInfo = new SessionAttachInfo(headnode, sessionId); successFlag = false; retryCount = 0; const int attachTimeoutMs = 15000; while (!successFlag && retryCount++ < retryCountMax) { try { session = DurableSession.AttachSession(attachInfo); successFlag = true; } catch (EndpointNotFoundException e) { Console.WriteLine("{0}", e.ToString()); } catch (CommunicationException e) { Console.WriteLine("{0}", e.ToString()); } catch (SessionException e) { Console.WriteLine("SessionException {0}, error code 0x{1:x}", e.ToString(), e.ErrorCode); // if session fatal errors happen, no retry if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.SessionFatalError)) { Console.WriteLine("SessionExceptionCategory : SessionFatalError {0}", e.ToString()); Console.WriteLine("No retry."); retryCount = retryCountMax; continue; } } catch (Exception e) { Console.WriteLine("General exception {0}", e.ToString()); } if (!successFlag) { Console.WriteLine("=== Sleep {0} ms to retry. Retry count left {1}. ===", retryIntervalMs, retryCountMax - retryCount); Thread.Sleep(retryIntervalMs); } } if (!successFlag) { Console.WriteLine("Attach durable session failed."); return; } successFlag = false; retryCount = 0; const int getTimeoutMs = 30000; const int clientCloseTimeoutMs = 15000; Console.WriteLine("Retrieving responses..."); while (!successFlag && retryCount++ < retryCountMax) { using (BrokerClient <IService1> client = new BrokerClient <IService1>(session)) { // GetResponses from the runtime system // EchoResponse class is created as you add Service Reference "EchoService" to the project try { //foreach (var response in client.GetResponses<EchoFaultResponse>(getTimeoutMs)) foreach (var response in client.GetResponses <EchoDelayResponse>(getTimeoutMs)) { try { //string reply = response.Result.EchoFaultResult ; int reply = response.Result.EchoDelayResult; Console.WriteLine("\tReceived response for delay request {0}: {1}", response.GetUserData <int>(), reply); } catch (FaultException <DivideByZeroException> e) { // Application exceptions Console.WriteLine("FaultException<DivideByZeroException> {0}", e.ToString()); } catch (FaultException e) { // Application exceptions Console.WriteLine("FaultException {0}", e.ToString()); } catch (RetryOperationException e) { // RetryOperationExceptions may or may not be recoverable Console.WriteLine("RetryOperationException {0}", e.ToString()); } } successFlag = true; Console.WriteLine("Done retrieving {0} responses", numRequests); } catch (TimeoutException e) { // Timeout exceptions Console.WriteLine("TimeoutException {0}", e.ToString()); } catch (CommunicationException e) { //CommunicationException Console.WriteLine("CommunicationException {0}", e.ToString()); } catch (SessionException e) { Console.WriteLine("SessionException {0}, error code 0x{1:x}", e.ToString(), e.ErrorCode); if (SOAFaultCode.Broker_BrokerUnavailable == e.ErrorCode) { Console.WriteLine("SessionException : BrokerUnavailable {0}", e.ToString()); } // Session Exceptions are unrecoverable unless they are application errors if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.ApplicationError)) { Console.WriteLine("SessionExceptionCategory : ApplicationError {0}", e.ToString()); } // if session fatal errors happen, no retry if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.SessionFatalError)) { Console.WriteLine("SessionExceptionCategory : SessionFatalError {0}", e.ToString()); Console.WriteLine("No retry."); retryCount = retryCountMax; continue; } } catch (Exception e) { //general exceptions Console.WriteLine("Exception {0}", e.ToString()); } try { client.Close(false, clientCloseTimeoutMs); } catch (Exception e) { Console.WriteLine("Exception", e.ToString()); } } if (!successFlag) { Console.WriteLine("=== Sleep {0} ms to retry. Retry count left {1}. ===", retryIntervalMs, retryCountMax - retryCount); Thread.Sleep(retryIntervalMs); } } //explict close the session to free the resource successFlag = false; retryCount = 0; Console.WriteLine("Close the session..."); while (!successFlag && retryCount++ < retryCountMax) { try { session.Close(true); successFlag = true; } catch (SessionException e) { Console.WriteLine("SessionException {0}, error code 0x{1:x}", e.ToString(), e.ErrorCode); // if session fatal errors happen, no retry if (SOAFaultCode.Category(e.ErrorCode).Equals(SOAFaultCodeCategory.SessionFatalError)) { Console.WriteLine("SessionExceptionCategory : SessionFatalError {0}", e.ToString()); Console.WriteLine("No retry."); retryCount = retryCountMax; continue; } } catch (Exception e) { Console.WriteLine("{0}", e.ToString()); } if (!successFlag) { Console.WriteLine("=== Sleep {0} ms to retry. Retry count left {1}. ===", retryIntervalMs, retryCountMax - retryCount); Thread.Sleep(retryIntervalMs); } } Console.WriteLine("Press any key to exit."); Console.ReadKey(); }