예제 #1
0
 /// <summary>
 /// Creates a session pool for the given client.
 /// </summary>
 /// <param name="client">The client to use for this session pool. Must not be null.</param>
 /// <param name="options">The options for this session pool. Must not be null.</param>
 /// <param name="logger">The logger to use. May be null, in which case the default logger is used.</param>
 public SessionPool(SpannerClient client, SessionPoolOptions options, Logger logger)
 {
     _client              = GaxPreconditions.CheckNotNull(client, nameof(client));
     _clock               = _client.Settings.Clock ?? SystemClock.Instance;
     _scheduler           = _client.Settings.Scheduler ?? SystemScheduler.Instance;
     Options              = GaxPreconditions.CheckNotNull(options, nameof(options));
     _logger              = logger ?? Logger.DefaultLogger;
     _detachedSessionPool = new DetachedSessionPool(this);
 }
예제 #2
0
        public async Task Request_With_ConnectionPayload()
        {
            Snapshot.FullName();

            await TryTest(async ct =>
            {
                // arrange
                var payload = new Dictionary <string, object> {
                    ["Key"] = "Value"
                };
                var sessionInterceptor = new StubSessionInterceptor();
                using IWebHost host    = TestServerHelper.CreateServer(
                          x => x
                          .AddTypeExtension <StringSubscriptionExtensions>()
                          .AddSocketSessionInterceptor <ISocketSessionInterceptor>(
                              _ => sessionInterceptor),
                          out var port);

                var serviceCollection = new ServiceCollection();
                serviceCollection
                .AddProtocol <GraphQLWebSocketProtocolFactory>()
                .AddWebSocketClient(
                    "Foo",
                    c => c.Uri = new Uri("ws://localhost:" + port + "/graphql"))
                .ConfigureConnectionInterceptor(new StubConnectionInterceptor(payload));
                IServiceProvider services =
                    serviceCollection.BuildServiceProvider();

                ISessionPool sessionPool =
                    services.GetRequiredService <ISessionPool>();

                List <JsonDocument> results = new();
                MockDocument document       = new("subscription Test { onTest(id:1) }");
                OperationRequest request    = new("Test", document);

                // act
                var connection =
                    new WebSocketConnection(async _ => await sessionPool.CreateAsync("Foo", _));
                await foreach (var response in connection.ExecuteAsync(request, ct))
                {
                    if (response.Body is not null)
                    {
                        results.Add(response.Body);
                    }
                }

                // assert
                Dictionary <string, object> message =
                    Assert.IsType <Dictionary <string, object> >(
                        sessionInterceptor.InitializeConnectionMessage?.Payload);

                Assert.Equal(payload["Key"], message["Key"]);
            });
        }
예제 #3
0
 /// <summary>
 /// 初始化ServerContext
 /// </summary>
 /// <param name="pool">ServerContext使用的SessionPool(null则使用系统默认的SessionPool)</param>
 /// <param name="timeOut">Session超时时间(默认30分钟)</param>
 public static void Init(ISessionPool pool=null,TimeSpan? timeOut= null)
 {
     if (pool == null)
     {
         SessionPool = new DefaultSessionPoolImplement();
     }
     else
     {
         SessionPool = pool;
     }
     SessionPool.TimeOut = timeOut.HasValue ? timeOut.Value : new TimeSpan(0, 30, 0);
     Debug.WriteLine("ServerContext初始化成功,Session超时时间:"+SessionPool.TimeOut.TotalMinutes+"分钟");
 }
 /// <summary>
 /// Creates a session pool for the given client.
 /// </summary>
 /// <param name="client">The client to use for this session pool. Must not be null.</param>
 /// <param name="options">The options for this session pool. Must not be null.</param>
 /// <param name="logger">The logger to use. May be null, in which case the default logger is used.</param>
 public SessionPool(SpannerClient client, SessionPoolOptions options, Logger logger)
 {
     _client                      = GaxPreconditions.CheckNotNull(client, nameof(client));
     _clock                       = _client.Settings.Clock ?? SystemClock.Instance;
     _scheduler                   = _client.Settings.Scheduler ?? SystemScheduler.Instance;
     Options                      = GaxPreconditions.CheckNotNull(options, nameof(options));
     _logger                      = logger ?? Logger.DefaultLogger;
     _detachedSessionPool         = new DetachedSessionPool(this);
     _sessionAcquisitionSemaphore = new SemaphoreSlim(Options.MaximumConcurrentSessionCreates);
     if (Options.MaintenanceLoopDelay != TimeSpan.Zero)
     {
         Task.Run(() => PoolMaintenanceLoop(this));
     }
 }
예제 #5
0
 /// <summary>
 /// Creates a session pool for the given client.
 /// </summary>
 /// <param name="client">The client to use for this session pool. Must not be null.</param>
 /// <param name="options">The options for this session pool. Must not be null.</param>
 public SessionPool(SpannerClient client, SessionPoolOptions options)
 {
     Client                       = GaxPreconditions.CheckNotNull(client, nameof(client));
     _clock                       = client.Settings.Clock ?? SystemClock.Instance;
     _scheduler                   = client.Settings.Scheduler ?? SystemScheduler.Instance;
     Options                      = GaxPreconditions.CheckNotNull(options, nameof(options));
     _logger                      = client.Settings.Logger; // Just to avoid fetching it all the time
     _detachedSessionPool         = new DetachedSessionPool(this);
     _batchSessionCreateSemaphore = new SemaphoreSlim((int)Math.Ceiling(
                                                          Options.MaximumConcurrentSessionCreates / (double)Options.CreateSessionMaximumBatchSize));
     if (Options.MaintenanceLoopDelay != TimeSpan.Zero)
     {
         Task.Run(() => PoolMaintenanceLoop(this));
     }
 }
예제 #6
0
        public async Task Simple_Request()
        {
            Snapshot.FullName();

            await TryTest(async ct =>
            {
                // arrange
                using IWebHost host = TestServerHelper.CreateServer(
                          x => x.AddTypeExtension <StringSubscriptionExtensions>(),
                          out var port);
                var serviceCollection = new ServiceCollection();
                serviceCollection
                .AddProtocol <GraphQLWebSocketProtocolFactory>()
                .AddWebSocketClient(
                    "Foo",
                    c => c.Uri            = new Uri("ws://localhost:" + port + "/graphql"));
                IServiceProvider services =
                    serviceCollection.BuildServiceProvider();

                ISessionPool sessionPool =
                    services.GetRequiredService <ISessionPool>();

                List <JsonDocument> results = new();
                MockDocument document       = new("subscription Test { onTest(id:1) }");
                OperationRequest request    = new("Test", document);

                // act
                var connection =
                    new WebSocketConnection(async _ => await sessionPool.CreateAsync("Foo", _));
                await foreach (var response in connection.ExecuteAsync(request, ct))
                {
                    if (response.Body is not null)
                    {
                        results.Add(response.Body);
                    }
                }


                // assert
                results.Select(x => x.RootElement.ToString()).ToList().MatchSnapshot();
            });
        }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BargainFinderMaxSoapActivity" /> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 public BargainFinderMaxSoapActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool)
 {
     this.sessionPool        = sessionPool;
     this.soapServiceFactory = soapServiceFactory;
 }
예제 #8
0
        public async Task Parallel_Request_SameSocket()
        {
            Snapshot.FullName();

            await TryTest(async ct =>
            {
                // arrange
                using IWebHost host = TestServerHelper
                                      .CreateServer(
                          x => x.AddTypeExtension <StringSubscriptionExtensions>(),
                          out var port);

                ServiceCollection serviceCollection = new();
                serviceCollection
                .AddProtocol <GraphQLWebSocketProtocolFactory>()
                .AddWebSocketClient(
                    "Foo",
                    c => c.Uri            = new Uri("ws://localhost:" + port + "/graphql"));
                IServiceProvider services = serviceCollection.BuildServiceProvider();

                ISessionPool sessionPool = services.GetRequiredService <ISessionPool>();
                ConcurrentDictionary <int, List <JsonDocument> > results = new();

                async Task CreateSubscription(int id)
                {
                    var connection = new WebSocketConnection(
                        async cancellationToken =>
                        await sessionPool.CreateAsync("Foo", cancellationToken));
                    var document = new MockDocument(
                        $"subscription Test {{ onTest(id:{id.ToString()}) }}");
                    var request = new OperationRequest("Test", document);
                    await foreach (var response in connection.ExecuteAsync(request, ct))
                    {
                        if (response.Body is not null)
                        {
                            results.AddOrUpdate(id,
                                                _ => new List <JsonDocument> {
                                response.Body
                            },
                                                (_, l) =>
                            {
                                l.Add(response.Body);
                                return(l);
                            });
                        }
                    }
                }

                // act
                var list = new List <Task>();
                for (var i = 0; i < 15; i++)
                {
                    list.Add(CreateSubscription(i));
                }

                await Task.WhenAll(list);

                // assert
                var str = "";
                foreach (KeyValuePair <int, List <JsonDocument> > sub in results.OrderBy(x => x.Key))
                {
                    JsonDocument[] jsonDocuments = sub.Value.ToArray();

                    str += "Operation " + sub.Key + "\n";
                    for (var index = 0; index < jsonDocuments.Length; index++)
                    {
                        str += "Operation " + jsonDocuments[index].RootElement + "\n";
                    }
                }

                str.MatchSnapshot();
            });
        }
예제 #9
0
        public async Task LoadTest_MessagesReceivedInCorrectOrder()
        {
            // arrange
            CancellationToken ct = new CancellationTokenSource(20_000).Token;

            using IWebHost host = TestServerHelper
                                  .CreateServer(
                      x => x.AddTypeExtension <StringSubscriptionExtensions>(),
                      out var port);

            ServiceCollection serviceCollection = new();

            serviceCollection
            .AddProtocol <GraphQLWebSocketProtocolFactory>();


            for (var i = 0; i < 10; i++)
            {
                serviceCollection.AddWebSocketClient(
                    "Foo" + i,
                    c => c.Uri = new Uri("ws://localhost:" + port + "/graphql"));
            }

            IServiceProvider services = serviceCollection.BuildServiceProvider();

            ISessionPool sessionPool = services.GetRequiredService <ISessionPool>();

            var globalCounter = 0;

            async Task?CreateSubscription(int client, int id)
            {
                var connection =
                    new WebSocketConnection(async ct =>
                                            await sessionPool.CreateAsync("Foo" + client, ct));
                var document =
                    new MockDocument($"subscription Test {{ countUp }}");
                var request = new OperationRequest("Test", document);
                var counter = 0;

                await foreach (var response in connection.ExecuteAsync(request, ct))
                {
                    if (response.Body is not null)
                    {
                        Interlocked.Increment(ref globalCounter);
                        var received = response.Body.RootElement
                                       .GetProperty("data")
                                       .GetProperty("countUp")
                                       .GetInt32();

                        if (counter != received)
                        {
                            throw new InvalidOperationException();
                        }

                        counter++;
                    }
                }
            }

            // act
            var list = new List <Task>();

            for (var i = 0; i < 10; i++)
            {
                for (var j = 0; j < 10; j++)
                {
                    list.Add(CreateSubscription(i, j));
                }
            }

            await Task.WhenAll(list);

            // assert
            Assert.Equal(10000, globalCounter);
        }
예제 #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="IgnoreTransactionActivity" /> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 public IgnoreTransactionActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool)
 {
     this.soapServiceFactory = soapServiceFactory;
     this.sessionPool        = sessionPool;
 }
예제 #11
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PassengerDetailsContactActivity" /> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 public PassengerDetailsContactActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool)
 {
     this.soapServiceFactory = soapServiceFactory;
     this.sessionPool        = sessionPool;
 }
예제 #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="TravelItineraryReadActivity"/> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 public TravelItineraryReadActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool)
 {
     this.soapServiceFactory = soapServiceFactory;
     this.sessionPool        = sessionPool;
 }
예제 #13
0
 /// <summary>
 /// Initializes a new instance of the <see cref="InitialSoapActivity" /> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 /// <param name="data">The data.</param>
 public InitialSoapActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool, ISoapWorkflowData data)
 {
     this.soapServiceFactory = soapServiceFactory;
     this.sessionPool        = sessionPool;
     this.data = data;
 }
예제 #14
0
 /// <summary>
 /// Initializes a new instance of the <see cref="EnhancedAirBookActivity"/> class.
 /// </summary>
 /// <param name="soapServiceFactory">The SOAP service factory.</param>
 /// <param name="sessionPool">The session pool.</param>
 public EnhancedAirBookActivity(SoapServiceFactory soapServiceFactory, ISessionPool sessionPool)
 {
     this.soapServiceFactory = soapServiceFactory;
     this.sessionPool        = sessionPool;
 }