Skip to content

Instantly share code, notes, and snippets.

@yallie
Last active January 21, 2021 10:42
Show Gist options
  • Save yallie/eac36078d201299174eb82c2721a7d43 to your computer and use it in GitHub Desktop.
Save yallie/eac36078d201299174eb82c2721a7d43 to your computer and use it in GitHub Desktop.
Zyan: TcpEx global connection lock issue
// http://zyan.com.de
//
// Compile using: csc test.cs /r:Zyan.Communication.dll
//
// Start up test.exe several times.
// The first process is the server, the rest are clients.
//
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
using Zyan.Communication;
using Zyan.Communication.Protocols.Tcp;
class GlobalLockSuspicionTest
{
static void Main()
{
try
{
StartServer();
}
catch
{
StartClient();
}
}
// ------------ Server code --------------
static void StartServer()
{
var proto = new TcpDuplexServerProtocolSetup(4321);
using (var host = new ZyanComponentHost(nameof(GlobalLockSuspicionTest), proto))
{
host.RegisterComponent<IService, Service>();
host.SubscriptionCanceled += (s, e) => Console.WriteLine("Subscription canceled: {0}.{1}", e.ComponentType, e.DelegateMemberName);
Console.WriteLine("Server started. Press ENTER to quit.");
Console.ReadLine();
}
}
public class Service : IService
{
private static int Counter { get; set; }
public string Hello()
{
Counter++;
Console.WriteLine("Called: " + Counter);
return "Hello: " + Counter;
}
}
// ------------ Shared code --------------
public interface IService
{
string Hello();
}
// ------------ Client code --------------
static void StartClient()
{
var proto = new TcpDuplexClientProtocolSetup();
var url = proto.FormatUrl("localhost", 4321, nameof(GlobalLockSuspicionTest));
using (var conn = new ZyanConnection(url))
{
var proxy = conn.CreateProxy<IService>();
Console.WriteLine("Client started. Commands: H = hello, P = poll, C = connect, ^C to quit.");
while (true)
{
var command = Console.ReadLine();
switch (command.ToLower().FirstOrDefault())
{
case 'h':
var result = proxy.Hello();
Console.WriteLine("Server reply: {0}", result);
break;
case 'p':
Console.WriteLine("Polling...");
ThreadPool.QueueUserWorkItem(x => Poll(proxy));
break;
case 'c':
Console.WriteLine("Connecting to example.com...");
ThreadPool.QueueUserWorkItem(x => Connect());
break;
default:
Console.WriteLine("Unknown command");
break;
}
}
}
}
static void Connect()
{
try
{
var proto = new TcpDuplexClientProtocolSetup();
var url = proto.FormatUrl("example.com", 4321, nameof(GlobalLockSuspicionTest));
new ZyanConnection(url);
}
catch (Exception ex)
{
Console.WriteLine("Connection failed. Error message: {0}", ex.Message);
}
}
static void Poll(IService proxy)
{
for (var i = 0; i < 100; i++)
{
Thread.Sleep(TimeSpan.FromSeconds(1));
Console.WriteLine("Iteration #{0}: server reply: {1}", i, proxy.Hello());
}
}
}
@yallie
Copy link
Author

yallie commented Jan 12, 2021

>test.exe

Client started. Commands: H = hello, P = poll, C = connect, ^C to quit.
h
Server reply: Hello: 8
p
Polling...
Iteration #0: server reply: Hello: 9
Iteration #1: server reply: Hello: 10
Iteration #2: server reply: Hello: 11
Iteration #3: server reply: Hello: 12
c
Connecting to example.com...
Iteration #4: server reply: Hello: 13
Connection failed. Error message: Connection timed out: 93.184.216.34:4321
Iteration #5: server reply: Hello: 14
Iteration #6: server reply: Hello: 15
Iteration #7: server reply: Hello: 16

Note that after "Connecting to example.com" line the polling stops.
It continues after "Connection failed" message is received in a minute or so.

@yallie
Copy link
Author

yallie commented Jan 13, 2021

Related issue: zyanfx/Zyan#85

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment