Beispiel #1
0
        private async Task HandleAsync(Server server, ClientMessageConnection connection, ClientMessage requestMessage,
                                       Func <Server, ClientMessageConnection, ClientMessage, ValueTask> handler)
        {
            var correlationId = requestMessage.CorrelationId;

            async Task SendResponseAsync(ClientMessage response)
            {
                response.CorrelationId = requestMessage.CorrelationId;
                response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await connection.SendAsync(response).CfAwait();
            }

            async Task SendEventAsync(ClientMessage eventMessage, long correlationId)
            {
                eventMessage.CorrelationId = correlationId;
                eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await connection.SendAsync(eventMessage).CfAwait();
            }

            switch (requestMessage.MessageType)
            {
            // handle authentication
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                var request         = ClientAuthenticationServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAuthenticationServerCodec.EncodeResponse(
                    0, server.Address, server.MemberId, SerializationService.SerializerVersion,
                    "4.0", 1, server.ClusterId, false);
                await SendResponseAsync(responseMessage).CfAwait();

                break;
            }

            // handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                var request         = ClientAddClusterViewListenerServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendResponseAsync(responseMessage).CfAwait();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(server.MemberId, server.Address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await SendEventAsync(eventMessage, correlationId).CfAwait();
                    });
                break;
            }

            // handle others
            default:
                await handler(server, connection, requestMessage).CfAwait();

                break;
            }
        }
Beispiel #2
0
        private async Task ReceiveMessageAsync(ClientMessageConnection connection, ClientMessage requestMessage)
        {
            var correlationId = requestMessage.CorrelationId;

            switch (requestMessage.MessageType)
            {
            // handle authentication
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                var request         = ClientAuthenticationServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAuthenticationServerCodec.EncodeResponse(
                    0, _address, _memberId, SerializationService.SerializerVersion,
                    "4.0", 1, _clusterId, false);
                await SendAsync(connection, responseMessage, correlationId).CAF();

                break;
            }

            // handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                var request         = ClientAddClusterViewListenerServerCodec.DecodeRequest(requestMessage);
                var responseMessage = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendAsync(connection, responseMessage, correlationId).CAF();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CAF();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(_memberId, _address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await SendAsync(connection, eventMessage, correlationId).CAF();
                    });
                break;
            }

            // handle others
            default:
                await _handler(this, connection, requestMessage).CAF();

                break;
            }
        }
Beispiel #3
0
        public async Task CanRetryAndTimeout()
        {
            var address = NetworkAddress.Parse("127.0.0.1:11001");

            HConsole.Configure(x => x.Configure(this).SetIndent(0).SetPrefix("TEST"));
            HConsole.WriteLine(this, "Begin");

            HConsole.WriteLine(this, "Start server");
            await using var server = new Server(address, async(xsvr, xconn, xmsg)
                                                => await HandleAsync(xsvr, xconn, xmsg, async(svr, conn, msg) =>
            {
                async Task ResponseAsync(ClientMessage response)
                {
                    response.CorrelationId = msg.CorrelationId;
                    response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                    await conn.SendAsync(response).CfAwait();
                }

                async Task EventAsync(ClientMessage eventMessage)
                {
                    eventMessage.CorrelationId = msg.CorrelationId;
                    eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                    await conn.SendAsync(eventMessage).CfAwait();
                }

                switch (msg.MessageType)
                {
                // must handle auth
                case ClientAuthenticationServerCodec.RequestMessageType:
                    var authRequest  = ClientAuthenticationServerCodec.DecodeRequest(msg);
                    var authResponse = ClientAuthenticationServerCodec.EncodeResponse(
                        0, address, Guid.NewGuid(), SerializationService.SerializerVersion,
                        "4.0", 1, Guid.NewGuid(), false);
                    await ResponseAsync(authResponse).CfAwait();
                    break;

                // must handle events
                case ClientAddClusterViewListenerServerCodec.RequestMessageType:
                    var addRequest  = ClientAddClusterViewListenerServerCodec.DecodeRequest(msg);
                    var addResponse = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                    await ResponseAsync(addResponse).CfAwait();

                    _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();
                        var eventMessage = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(1, new[]
                        {
                            new MemberInfo(Guid.NewGuid(), address, new MemberVersion(4, 0, 0), false, new Dictionary <string, string>()),
                        });
                        await EventAsync(eventMessage).CfAwait();
                    });

                    break;

                default:
                    HConsole.WriteLine(svr, "Respond with error.");
                    var response = CreateErrorMessage(RemoteError.RetryableHazelcast);
                    await ResponseAsync(response).CfAwait();
                    break;
                }
            }), LoggerFactory);
            await server.StartAsync().CfAwait();

            HConsole.WriteLine(this, "Start client");
            var options = HazelcastOptions.Build(configure: (configuration, options) =>
            {
                options.Networking.Addresses.Add("127.0.0.1:11001");
            });

            await using var client = (HazelcastClient) await HazelcastClientFactory.StartNewClientAsync(options);

            HConsole.WriteLine(this, "Send message");
            var message = ClientPingServerCodec.EncodeRequest();

            var token = new CancellationTokenSource(3_000).Token;
            await AssertEx.ThrowsAsync <TaskCanceledException>(async() => await client.Cluster.Messaging.SendAsync(message, token).CfAwait());

            // TODO dispose the client, the server
            await server.StopAsync().CfAwait();
        }
        private async ValueTask ServerHandler(Server s, ClientMessageConnection conn, ClientMessage msg)
        {
            async Task SendResponseAsync(ClientMessage response)
            {
                response.CorrelationId = msg.CorrelationId;
                response.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await conn.SendAsync(response).CfAwait();
            }

            async Task SendEventAsync(ClientMessage eventMessage, long correlationId)
            {
                eventMessage.CorrelationId = correlationId;
                eventMessage.Flags        |= ClientMessageFlags.BeginFragment | ClientMessageFlags.EndFragment;
                await conn.SendAsync(eventMessage).CfAwait();
            }

            async Task SendErrorAsync(RemoteError error, string message)
            {
                var errorHolders = new List <ErrorHolder>
                {
                    new ErrorHolder(error, "?", message, Enumerable.Empty <StackTraceElement>())
                };
                var response = ErrorsServerCodec.EncodeResponse(errorHolders);

                await SendResponseAsync(response).CfAwait();
            }

            var state   = (ServerState)s.State;
            var address = s.Address;

            const int partitionsCount = 2;

            switch (msg.MessageType)
            {
            // must handle auth
            case ClientAuthenticationServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) Authentication");
                var authRequest  = ClientAuthenticationServerCodec.DecodeRequest(msg);
                var authResponse = ClientAuthenticationServerCodec.EncodeResponse(
                    0, address, s.MemberId, SerializationService.SerializerVersion,
                    "4.0", partitionsCount, s.ClusterId, false);
                await SendResponseAsync(authResponse).CfAwait();

                break;
            }

            // must handle events
            case ClientAddClusterViewListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) AddClusterViewListener");
                var addRequest  = ClientAddClusterViewListenerServerCodec.DecodeRequest(msg);
                var addResponse = ClientAddClusterViewListenerServerCodec.EncodeResponse();
                await SendResponseAsync(addResponse).CfAwait();

                _ = Task.Run(async() =>
                    {
                        await Task.Delay(500).CfAwait();

                        const int membersVersion = 1;
                        var memberVersion        = new MemberVersion(4, 0, 0);
                        var memberAttributes     = new Dictionary <string, string>();
                        var membersEventMessage  = ClientAddClusterViewListenerServerCodec.EncodeMembersViewEvent(membersVersion, new[]
                        {
                            new MemberInfo(state.MemberIds[0], state.Addresses[0], memberVersion, false, memberAttributes),
                            new MemberInfo(state.MemberIds[1], state.Addresses[1], memberVersion, false, memberAttributes),
                        });
                        await SendEventAsync(membersEventMessage, msg.CorrelationId).CfAwait();

                        await Task.Delay(500).CfAwait();

                        const int partitionsVersion = 1;
                        var partitionsEventMessage  = ClientAddClusterViewListenerServerCodec.EncodePartitionsViewEvent(partitionsVersion, new[]
                        {
                            new KeyValuePair <Guid, IList <int> >(state.MemberIds[0], new List <int> {
                                0
                            }),
                            new KeyValuePair <Guid, IList <int> >(state.MemberIds[1], new List <int> {
                                1
                            }),
                        });
                        await SendEventAsync(partitionsEventMessage, msg.CorrelationId).CfAwait();
                    });

                break;
            }

            // create object
            case ClientCreateProxyServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) CreateProxy");
                var createRequest  = ClientCreateProxyServerCodec.DecodeRequest(msg);
                var createResponse = ClientCreateProxiesServerCodec.EncodeResponse();
                await SendResponseAsync(createResponse).CfAwait();

                break;
            }

            // subscribe
            case MapAddEntryListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) AddEntryListener");
                var addRequest = MapAddEntryListenerServerCodec.DecodeRequest(msg);
                state.Subscribed = true;
                state.SubscriptionCorrelationId = msg.CorrelationId;
                var addResponse = MapAddEntryListenerServerCodec.EncodeResponse(state.SubscriptionId);
                await SendResponseAsync(addResponse).CfAwait();

                break;
            }

            // unsubscribe
            // server 1 removes on first try, server 2 removes on later tries
            case MapRemoveEntryListenerServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) RemoveEntryListener");
                var removeRequest = MapRemoveEntryListenerServerCodec.DecodeRequest(msg);
                var removed       = state.Subscribed && removeRequest.RegistrationId == state.SubscriptionId;
                removed &= state.Id == 0 || state.UnsubscribeCount++ > 0;
                if (removed)
                {
                    state.Subscribed = false;
                }
                HConsole.WriteLine(this, $"(server{state.Id}) Subscribed={state.Subscribed}");
                var removeResponse = MapRemoveEntryListenerServerCodec.EncodeResponse(removed);
                await SendResponseAsync(removeResponse).CfAwait();

                break;
            }

            // add to map & trigger event
            case MapSetServerCodec.RequestMessageType:
            {
                HConsole.WriteLine(this, $"(server{state.Id}) Set");
                var setRequest  = MapSetServerCodec.DecodeRequest(msg);
                var setResponse = MapSetServerCodec.EncodeResponse();
                await SendResponseAsync(setResponse).CfAwait();

                HConsole.WriteLine(this, $"(server{state.Id}) Subscribed={state.Subscribed}");

                if (state.Subscribed)
                {
                    HConsole.WriteLine(this, $"(server{state.Id}) Trigger event");
                    var key        = setRequest.Key;
                    var value      = setRequest.Value;
                    var addedEvent = MapAddEntryListenerServerCodec.EncodeEntryEvent(key, value, value, value, (int)MapEventTypes.Added, state.SubscriptionId, 1);
                    await SendEventAsync(addedEvent, state.SubscriptionCorrelationId).CfAwait();
                }
                break;
            }

            // unexpected message = error
            default:
            {
                // RemoteError.Hazelcast or RemoteError.RetryableHazelcast
                var messageName = MessageTypeConstants.GetMessageTypeName(msg.MessageType);
                await SendErrorAsync(RemoteError.Hazelcast, $"MessageType {messageName} (0x{msg.MessageType:X}) not implemented.").CfAwait();

                break;
            }
            }
        }