Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 58 additions & 17 deletions Hazelcast.Net/Hazelcast.Client.Spi/ProxyManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,25 +108,58 @@ public ICollection<IDistributedObject> GetDistributedObjects()
return new ReadOnlyCollection<IDistributedObject>(_proxies.Values.ToList<IDistributedObject>());
}

public ClientProxy GetOrCreateProxy<T>(string service, string id)
public ClientProxy GetOrCreateProxy<T>(string service, string id) where T : IDistributedObject
{
var ns = new ObjectNamespace(service, id);
ClientProxy proxy;
_proxies.TryGetValue(ns, out proxy);
var requestedInterface = typeof (T);
if (proxy != null)
{
return proxy;
// only return the existing proxy, if the requested type args match
var proxyInterface = proxy.GetType().GetInterface(requestedInterface.Name);
var proxyArgs = proxyInterface.GetGenericArguments();
var requestedArgs = requestedInterface.GetGenericArguments();
if (proxyArgs.SequenceEqual(requestedArgs))
{
// the proxy we found matches what we were looking for
return proxy;
}

// create a new proxy, which matches the interface requested
proxy = makeProxy<T>(service, id, requestedInterface);
}
ClientProxyFactory factory;
else
{
// create a new proxy, which needs initialization on server.
proxy = makeProxy<T>(service, id, requestedInterface);
InitializeWithRetry(proxy);
}

proxy.SetContext(new ClientContext(_client.GetSerializationService(),
_client.GetClientClusterService(),
_client.GetClientPartitionService(), _client.GetInvocationService(), _client.GetClientExecutionService(),
_client.GetListenerService(),
this, _client.GetClientConfig()));
proxy.PostInit();

_proxies.AddOrUpdate(ns, n => proxy, (n, oldProxy) => {
Logger.Warning("Replacing old proxy for " + oldProxy.GetName() + " of type " + oldProxy.GetType() + " with " + proxy.GetType());
return proxy;
});
return proxy;
}

private ClientProxy makeProxy<T>(string service, string id, Type requestedInterface)
{
ClientProxyFactory factory;
_proxyFactories.TryGetValue(service, out factory);
if (factory == null)
{
throw new ArgumentException("No factory registered for service: " + service);
}
var clientProxy = factory(typeof (T), id);
InitializeWithRetry(clientProxy);
return _proxies.GetOrAdd(ns, clientProxy);
var clientProxy = factory(requestedInterface, id);
return clientProxy;
}

public ClientProxy GetProxy(string service, string id)
Expand Down Expand Up @@ -225,9 +258,8 @@ internal static ClientProxy ProxyFactory(Type proxyType, Type interfaceType, str
{
if (proxyType.ContainsGenericParameters)
{
var genericTypeArguments = interfaceType.GetGenericArguments();
var mgType = proxyType.MakeGenericType(genericTypeArguments);
return Activator.CreateInstance(mgType, name, id) as ClientProxy;
var typeWithParams = GetTypeWithParameters(proxyType, interfaceType);
return Activator.CreateInstance(typeWithParams, name, id) as ClientProxy;
}
return Activator.CreateInstance(proxyType, name, id) as ClientProxy;
}
Expand All @@ -253,7 +285,22 @@ private Address FindNextAddressToCreateARequest()
return liteMember != null ? liteMember.GetAddress() : null;
}

private void Initialize(ClientProxy clientProxy)
private static Type GetTypeWithParameters(Type proxyType, Type interfaceType)
{
var genericTypeArguments = interfaceType.GetGenericArguments();
if (genericTypeArguments.Length == proxyType.GetGenericArguments().Length)
{
return proxyType.MakeGenericType(genericTypeArguments);
}
var types = new Type[proxyType.GetGenericArguments().Length];
for (var i = 0; i < types.Length; i++)
{
types[i] = typeof (object);
}
return proxyType.MakeGenericType(types);
}

private void InitializeOnServer(ClientProxy clientProxy)
{
var initializationTarget = FindNextAddressToCreateARequest();
var invocationTarget = initializationTarget;
Expand All @@ -278,12 +325,6 @@ private void Initialize(ClientProxy clientProxy)
{
throw ExceptionUtil.Rethrow(e);
}
clientProxy.SetContext(new ClientContext(_client.GetSerializationService(),
_client.GetClientClusterService(),
_client.GetClientPartitionService(), _client.GetInvocationService(), _client.GetClientExecutionService(),
_client.GetListenerService(),
this, _client.GetClientConfig()));
clientProxy.PostInit();
}

private void InitializeWithRetry(ClientProxy clientProxy)
Expand All @@ -294,7 +335,7 @@ private void InitializeWithRetry(ClientProxy clientProxy)
{
try
{
Initialize(clientProxy);
InitializeOnServer(clientProxy);
return;
}
catch (Exception e)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.

using System;
using System.Threading;
using Hazelcast.Core;
using NUnit.Framework;
Expand Down Expand Up @@ -40,19 +41,37 @@ public void TestDistributedObjectListener()
[Test]
public void TestGetDistributedObjects()
{
var queue = Client.GetMap<int, int>(TestSupport.RandomString());
var map = Client.GetMap<int, int>(TestSupport.RandomString());
var topic = Client.GetTopic<int>(TestSupport.RandomString());
var semaphore = Client.GetSemaphore(TestSupport.RandomString());


Assert.AreEqual(3, Client.GetDistributedObjects().Count);

queue.Destroy();
map.Destroy();
topic.Destroy();
semaphore.Destroy();

Assert.AreEqual(0, Client.GetDistributedObjects().Count);
}

[Test]
public void TestGetDistributedObjectsFromAnotherClient()
{
String mapName = TestSupport.RandomString();
var map = Client.GetMap<int, int>(mapName);
Client.GetTopic<int>(TestSupport.RandomString());
Client.GetSemaphore(TestSupport.RandomString());

map.Put(1, 1);
var client2 = CreateClient();

Assert.AreEqual(3, client2.GetDistributedObjects().Count);

var map2 = client2.GetMap<int, int>(mapName);
Assert.AreEqual(1, map2.Get(1));
}

private class DistributedObjectListener : IDistributedObjectListener
{
private readonly CountdownEvent _createdLatch;
Expand Down