public void MergedWith_OneNull()
 {
     CallSettings settings1 = new CallSettings(null, null, null, null, null, null);
     CallSettings settings2 = null;
     Assert.Same(settings1, settings1.MergedWith(settings2));
     Assert.Same(settings1, settings2.MergedWith(settings1));
 }
        public void WithCancellationToken()
        {
            CancellationToken token1 = new CancellationTokenSource().Token;
            CallTiming timing = CallTiming.FromExpiration(Expiration.None);
            var original = new CallSettings(token1, null, timing, null, null, null);

            CancellationToken token2 = new CancellationTokenSource().Token;
            var result = original.WithCancellationToken(token2);
            Assert.Same(timing, result.Timing);
            Assert.Equal(token2, result.CancellationToken);
        }
        public void WithCallTiming_NonNull()
        {
            CallTiming timing1 = CallTiming.FromExpiration(Expiration.None);
            CallTiming timing2 = CallTiming.FromDeadline(DateTime.UtcNow);

            CancellationToken token = new CancellationTokenSource().Token;

            var original = new CallSettings(token, null, timing1, null, null, null);
            var result = original.WithCallTiming(timing2);
            Assert.Same(timing2, result.Timing);
            Assert.Equal(token, result.CancellationToken);
        }
        public void MergedWith_BothNonNull()
        {
            CallTiming timing1 = CallTiming.FromExpiration(Expiration.None);
            CallTiming timing2 = CallTiming.FromDeadline(DateTime.UtcNow);

            CancellationToken token = new CancellationTokenSource().Token;

            var settings1 = new CallSettings(token, null, timing1, null, null, null);
            var settings2 = new CallSettings(null, null, timing2, null, null, null);
            var merged = settings1.MergedWith(settings2);
            Assert.Equal(token, merged.CancellationToken);
            Assert.Same(timing2, merged.Timing);
        }
 public void Clone()
 {
     var clock = new Mock<IClock>();
     var callSettings = new CallSettings(new CancellationTokenSource().Token, null, null, null, null, null);
     var settings = new TestSettings
     {
         CallSettings = callSettings,
         Clock = clock.Object,
     };
     var clonedSettings = settings.Clone();
     Assert.NotSame(settings, clonedSettings);
     // CallSettings is immutable, so just a reference copy is fine.
     Assert.Same(callSettings, clonedSettings.CallSettings);
     Assert.Equal(settings.UserAgent, clonedSettings.UserAgent);
     Assert.Equal(clock.Object, clonedSettings.Clock);
 }
        public void Merge_HeaderMutationOrdering()
        {
            Action<Metadata> clearAndAddFoo = m => { m.Clear(); m.Add("foo", "bar"); };
            Action<Metadata> addSample = m => m.Add("sample", "value");

            CallSettings clearAndAddFooSettings = new CallSettings(null, null, null, clearAndAddFoo, null, null);
            CallSettings addSampleSettings = new CallSettings(null, null, null, addSample, null, null);

            var merged1 = CallSettings.Merge(clearAndAddFooSettings, addSampleSettings);
            var merged2 = CallSettings.Merge(addSampleSettings, clearAndAddFooSettings);

            // Original should be called first, so merged1 should end up with foo and sample;
            // merged2 should end up with just foo.
            var metadata = new Metadata();
            merged1.HeaderMutation(metadata);
            Assert.Equal(2, metadata.Count);

            metadata = new Metadata();
            merged2.HeaderMutation(metadata);
            Assert.Equal(1, metadata.Count);
        }
 public void ToCallOptions_All()
 {
     var mockClock = new Mock<IClock>();
     var callSettings = new CallSettings
     (
         headerMutation: metadata => metadata.Add(new Metadata.Entry("1", "one")),
         timing: CallTiming.FromExpiration(Expiration.None),
         cancellationToken: new CancellationTokenSource().Token,
         writeOptions: new WriteOptions(WriteFlags.NoCompress),
         propagationToken: null, // Not possible to create/mock
         credentials: null // Not possible to create/mock
     );
     var options = callSettings.ToCallOptions(null, mockClock.Object);
     Assert.Equal(1, options.Headers.Count);
     Assert.Equal("[Entry: key=1, value=one]", options.Headers[0].ToString());
     Assert.Null(options.Deadline);
     Assert.Equal(callSettings.CancellationToken, options.CancellationToken);
     Assert.Same(callSettings.WriteOptions, options.WriteOptions);
 }
 /// <summary>
 /// Returns the contents of the requested row, optionally applying the specified Reader filter.
 /// </summary>
 /// <remarks>
 /// <para>
 /// This method simply delegates to <see cref="ReadRowAsync(TableName, BigtableByteString, RowFilter, CallSettings)"/>.
 /// </para>
 /// </remarks>
 /// <param name="tableName">
 /// The unique name of the table from which to read. Must not be null.
 /// </param>
 /// <param name="rowKey">
 /// The key of the row to read. Must not be empty.
 /// </param>
 /// <param name="filter">
 /// The filter to apply to the contents of the specified row. If null,
 /// reads the entirety of the row.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// The row from the server or null if it does not exist.
 /// </returns>
 public virtual Row ReadRow(
     TableName tableName,
     BigtableByteString rowKey,
     RowFilter filter          = null,
     CallSettings callSettings = null) =>
 Task.Run(() => ReadRowAsync(tableName, rowKey, filter, callSettings)).ResultWithUnwrappedExceptions();
Example #9
0
 /// <summary>
 /// Report an individual error event.
 ///
 /// This endpoint accepts &lt;strong&gt;either&lt;/strong&gt; an OAuth token,
 /// &lt;strong&gt;or&lt;/strong&gt; an
 /// &lt;a href="https://support.google.com/cloud/answer/6158862"&gt;API key&lt;/a&gt;
 /// for authentication. To use an API key, append it to the URL as the value of
 /// a `key` parameter. For example:
 /// &lt;pre&gt;POST https://clouderrorreporting.googleapis.com/v1beta1/projects/example-project/events:report?key=123ABC456&lt;/pre&gt;
 /// </summary>
 /// <param name="request">
 /// The request object containing all of the parameters for the API call.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// A Task containing the RPC response.
 /// </returns>
 public virtual Task <ReportErrorEventResponse> ReportErrorEventAsync(
     ReportErrorEventRequest request,
     CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
 partial void Modify_AnnotateTextRequest(ref AnnotateTextRequest request, ref CallSettings settings);
 partial void Modify_AnalyzeEntitiesRequest(ref AnalyzeEntitiesRequest request, ref CallSettings settings);
 /// <summary>
 /// A convenience method that provides all the features that analyzeSentiment,
 /// analyzeEntities, and analyzeSyntax provide in one call.
 /// </summary>
 /// <param name="request">
 /// The request object containing all of the parameters for the API call.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// The RPC response.
 /// </returns>
 public virtual AnnotateTextResponse AnnotateText(
     AnnotateTextRequest request,
     CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Finds named entities (currently proper names and common nouns) in the text
 /// along with entity types, salience, mentions for each entity, and
 /// other properties.
 /// </summary>
 /// <param name="request">
 /// The request object containing all of the parameters for the API call.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// A Task containing the RPC response.
 /// </returns>
 public virtual Task <AnalyzeEntitiesResponse> AnalyzeEntitiesAsync(
     AnalyzeEntitiesRequest request,
     CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
Example #14
0
        /// <summary>
        /// Looks up a single entity by key asynchronously.
        /// </summary>
        /// <remarks>This method simply delegates to <see cref="LookupAsync(IEnumerable{Key}, CallSettings)"/>.</remarks>
        /// <param name="key">The key to look up. Must not be null, and must be complete.</param>
        /// <param name="callSettings">If not null, applies overrides to this RPC call.</param>
        /// <returns>The entity with the specified key, or <c>null</c> if no such entity exists.</returns>
        public virtual async Task <Entity> LookupAsync(Key key, CallSettings callSettings = null)
        {
            var results = await LookupAsync(new[] { key }, callSettings).ConfigureAwait(false);

            return(results[0]);
        }
Example #15
0
 /// <summary>
 /// Looks up a single entity by key.
 /// </summary>
 /// <remarks>This method simply delegates to <see cref="Lookup(IEnumerable{Key}, CallSettings)"/>.</remarks>
 /// <param name="key">The key to look up. Must not be null, and must be complete.</param>
 /// <param name="callSettings">If not null, applies overrides to this RPC call.</param>
 /// <returns>The entity with the specified key, or <c>null</c> if no such entity exists.</returns>
 public virtual Entity Lookup(Key key, CallSettings callSettings = null) => Lookup(new[] { key }, callSettings)[0];
Example #16
0
 /// <summary>
 /// Lazily executes the given structured query in this transaction for asynchronous consumption.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Using a transaction ensures that a commit operation will fail if any of the entities returned
 /// by this query have been modified while the transaction is active. Note that modifications performed
 /// as part of this operation are not reflected in the query results.
 /// </para>
 /// <para>
 /// The results are requested lazily: no API calls will be made until the application starts
 /// iterating over the results. Iterating over the same <see cref="LazyDatastoreQuery"/> object
 /// multiple times will execute the query again, potentially returning different results.
 /// </para>
 /// </remarks>
 /// <param name="gqlQuery">The query to execute. Must not be null.</param>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <returns>An <see cref="AsyncLazyDatastoreQuery"/> representing the result of the query.</returns>
 public virtual AsyncLazyDatastoreQuery RunQueryLazilyAsync(GqlQuery gqlQuery, CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
Example #17
0
 /// <summary>
 /// Runs the given query eagerly and asynchronously in this transaction, retrieving all results in memory and indicating whether more
 /// results may be available beyond the query's limit. Use this method when your query has a limited
 /// number of results, for example to build a web application which fetches results in pages.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Using a transaction ensures that a commit operation will fail if any of the entities returned
 /// by this query have been modified while the transaction is active. Note that modifications performed
 /// as part of this operation are not reflected in the query results.
 /// </para>
 /// <para>The default implementation of this method delegates to <see cref="RunQueryLazilyAsync(GqlQuery, CallSettings)"/>
 /// and calls <see cref="AsyncLazyDatastoreQuery.GetAllResultsAsync"/> on the return value.</para>
 /// </remarks>
 /// <param name="query">The query to execute. Must not be null.</param>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <returns>A task representing the asynchronous operation. The result of the task is the complete set of query results.</returns>
 public virtual Task <DatastoreQueryResults> RunQueryAsync(GqlQuery query, CallSettings callSettings = null) =>
 RunQueryLazilyAsync(query, callSettings).GetAllResultsAsync();
Example #18
0
 /// <summary>
 /// Lazily executes the given structured query in this transaction.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Using a transaction ensures that a commit operation will fail if any of the entities returned
 /// by this query have been modified while the transaction is active. Note that modifications performed
 /// as part of this operation are not reflected in the query results.
 /// </para>
 /// <para>
 /// The results are requested lazily: no API calls will be made until the application starts
 /// iterating over the results. Iterating over the same <see cref="LazyDatastoreQuery"/> object
 /// multiple times will execute the query again, potentially returning different results.
 /// </para>
 /// </remarks>
 /// <param name="query">The query to execute. Must not be null.</param>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <returns>A <see cref="LazyDatastoreQuery"/> representing the the lazy query results.</returns>
 public virtual LazyDatastoreQuery RunQueryLazily(Query query, CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
Example #19
0
 /// <inheritdoc />
 public override Task <IReadOnlyList <Entity> > LookupAsync(IEnumerable <Key> keys, CallSettings callSettings = null) =>
 DatastoreDb.LookupImplAsync(_client, _projectId, _readOptions, keys, callSettings);
Example #20
0
        /// <inheritdoc />
        public override AsyncLazyDatastoreQuery RunQueryLazilyAsync(GqlQuery gqlQuery, CallSettings callSettings = null)
        {
            GaxPreconditions.CheckNotNull(gqlQuery, nameof(gqlQuery));
            var request = new RunQueryRequest
            {
                ProjectId   = _projectId,
                PartitionId = _partitionId,
                GqlQuery    = gqlQuery,
                ReadOptions = _readOptions
            };
            var streamer = new QueryStreamer(request, _client.RunQueryApiCall, callSettings);

            return(new AsyncLazyDatastoreQuery(streamer.Async()));
        }
        public void AllowAJoinRequestToBeDeleted()
        {
            // Create a solo party.
            _partyClient.CreateParty(new CreatePartyRequest(), _leaderMetadata);

            // Join matchmaking.
            var op = _gatewayClient.Join(new JoinRequest
            {
                MatchmakingType = "no_match"
            }, _leaderMetadata);

            Assert.AreEqual(LeaderPlayerId, op.Name);
            Assert.False(op.Done);

            // Verify that the party has not been matched yet. (Possibly flaky? The party might have been matched
            // between this call and the cancel operation).
            var fetchedOp = _operationsClient.GetOperation(LeaderPlayerId,
                                                           CallSettings.FromHeader(PitRequestHeaderName, _leaderPit));

            Assert.AreEqual(LeaderPlayerId, fetchedOp.Name);
            Assert.False(fetchedOp.Done);

            // Cancel matchmaking.
            _operationsClient.DeleteOperation(LeaderPlayerId,
                                              CallSettings.FromHeader(PitRequestHeaderName, _leaderPit));

            // Verify that there is no more information within the matchmaking system about the party/player.
            var rpcException = Assert.Throws <RpcException>(() =>
                                                            _operationsClient.GetOperation(LeaderPlayerId,
                                                                                           CallSettings.FromHeader(PitRequestHeaderName, _leaderPit)));

            Assert.AreEqual(StatusCode.NotFound, rpcException.Status.StatusCode);

            // Clean-up.
            _partyClient.DeleteParty(new DeletePartyRequest(), _leaderMetadata);
        }
 /// <summary>
 /// Analyzes the sentiment of the provided text.
 /// </summary>
 /// <param name="document">
 /// Input document.
 /// </param>
 /// <param name="cancellationToken">
 /// A <see cref="CancellationToken"/> to use for this RPC.
 /// </param>
 /// <returns>
 /// A Task containing the RPC response.
 /// </returns>
 public virtual Task <AnalyzeSentimentResponse> AnalyzeSentimentAsync(
     Document document,
     CancellationToken cancellationToken) => AnalyzeSentimentAsync(
     document,
     CallSettings.FromCancellationToken(cancellationToken));
Example #23
0
 /// <summary>
 /// Looks up a collection of entities by key asynchronously.
 /// </summary>
 /// <remarks>
 /// This call may perform multiple RPC operations in order to look up all keys.
 /// </remarks>
 /// <para>Datastore limits the number of entities that can be looked up in a single operation. When looking up a large
 /// number of entities, partition the look-ups into batches. See
 /// [Datastore limits](https://cloud.google.com/datastore/docs/concepts/limits) for more details on Datastore limits.</para>
 /// <param name="keys">The keys to look up. Must not be null, and every element must be non-null and refer to a complete key.</param>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <returns>A collection of entities with the same size as <paramref name="keys"/>, containing corresponding entity
 /// references, or <c>null</c> where the key was not found.</returns>
 public virtual Task <IReadOnlyList <Entity> > LookupAsync(IEnumerable <Key> keys, CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
 /// <summary>
 /// Analyzes the syntax of the text and provides sentence boundaries and
 /// tokenization along with part of speech tags, dependency trees, and other
 /// properties.
 /// </summary>
 /// <param name="request">
 /// The request object containing all of the parameters for the API call.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// The RPC response.
 /// </returns>
 public virtual AnalyzeSyntaxResponse AnalyzeSyntax(
     AnalyzeSyntaxRequest request,
     CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
Example #25
0
 /// <summary>
 /// Commits all mutations in this transaction.
 /// </summary>
 /// <remarks>
 /// <para>Any entities with incomplete keys that are assigned keys by this operation will be updated in memory
 /// with the server-allocated keys.</para>
 /// <para>Datastore limits the number of entities that can be modified in a Commit operation, and therefore one transaction. When modifying a large
 /// number of entities, partition the changes into multiple transactions. See
 /// [Datastore limits](https://cloud.google.com/datastore/docs/concepts/limits) for more details on Datastore limits.</para>
 /// </remarks>
 /// <exception cref="InvalidOperationException">The transaction has already been committed or rolled back.</exception>
 /// <returns>The response from the commit operation. This can be used to determine server-allocated keys.</returns>
 public virtual CommitResponse Commit(CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
 // Partial modifier methods contain '_' to ensure no name conflicts with RPC methods.
 partial void Modify_AnalyzeSentimentRequest(ref AnalyzeSentimentRequest request, ref CallSettings settings);
Example #27
0
 /// <summary>
 /// Commits all mutations in this transaction asynchronously.
 /// </summary>
 /// <remarks>
 /// <para>Any entities with incomplete keys that are assigned keys by this operation will be updated in memory
 /// with the server-allocated keys.</para>
 /// <para>Datastore limits the number of entities that can be modified in a Commit operation, and therefore one transaction. When modifying a large
 /// number of entities, partition the changes into multiple transactions. See
 /// [Datastore limits](https://cloud.google.com/datastore/docs/concepts/limits) for more details on Datastore limits.</para>
 /// </remarks>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <exception cref="InvalidOperationException">The transaction has already been committed or rolled back.</exception>
 /// <returns>The response from the commit operation. This can be used to determine server-allocated keys.</returns>
 public virtual Task <CommitResponse> CommitAsync(CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
 partial void Modify_AnalyzeSyntaxRequest(ref AnalyzeSyntaxRequest request, ref CallSettings settings);
        private async Task <MutateRowsResponse> MutateRowsImpl(MutateRowsRequest request, CallSettings callSettings)
        {
            var defaultSettings        = _client.DefaultSettings ?? new BigtableServiceApiSettings();
            var effectiveCallSettings  = defaultSettings.MutateRowsSettings.MergedWith(callSettings);
            var effectiveRetrySettings = defaultSettings.MutateRowsRetrySettings;

            // TODO: Should the request manager be using the retry filter? We would need to fabricate RpcExceptions
            StatusCode[] retryStatuses  = { StatusCode.DeadlineExceeded, StatusCode.Unavailable };
            var          requestManager = new BigtableMutateRowsRequestManager(retryStatuses, request);

            await Utilities.RetryOperationUntilCompleted(
                async() =>
            {
                var currentStream = _client.MutateRows(requestManager.NextRequest, callSettings);
                return(await ProcessCurrentStream(currentStream).ConfigureAwait(false) != ProcessingStatus.Retryable);
            },
                Clock,
                Scheduler,
                effectiveCallSettings,
                effectiveRetrySettings).ConfigureAwait(false);

            return(requestManager.BuildResponse());

            async Task <ProcessingStatus> ProcessCurrentStream(BigtableServiceApiClient.MutateRowsStream stream)
            {
                var cancellationToken = effectiveCallSettings.CancellationToken ?? default;
                var responseStream    = stream.ResponseStream;

                while (await responseStream.MoveNext(cancellationToken).ConfigureAwait(false))
                {
                    requestManager.SetStatus(responseStream.Current);
                }
                return(requestManager.OnOk());
            }
        }
 internal QueryStreamer(RunQueryRequest initialRequest, ApiCall <RunQueryRequest, RunQueryResponse> apiCall, CallSettings callSettings)
 {
     _initialRequest = GaxPreconditions.CheckNotNull(initialRequest, nameof(initialRequest)).Clone();
     _apiCall        = GaxPreconditions.CheckNotNull(apiCall, nameof(apiCall));
     _callSettings   = callSettings;
 }
        public void WithCallCredentials_NonNull()
        {
            AsyncAuthInterceptor interceptor = (context, metadata) => Task.Delay(0);
            var credentials1 = CallCredentials.FromInterceptor(interceptor);
            var credentials2 = CallCredentials.FromInterceptor(interceptor);
            Assert.NotSame(credentials1, credentials2);

            CancellationToken token = new CancellationTokenSource().Token;

            var original = new CallSettings(token, credentials1, null, null, null, null);
            var result = original.WithCallCredentials(credentials2);
            Assert.Same(credentials2, result.Credentials);
            Assert.Equal(token, result.CancellationToken);
        }
 internal BigtableServiceApiClient.ReadRowsStream ReadRowsInternal(ReadRowsRequest request, CallSettings callSettings) =>
 _client.ReadRows(request, callSettings);
 /// <summary>
 /// Mutates multiple rows in a batch. Each individual row is mutated
 /// atomically as in <see cref="MutateRow(MutateRowRequest, CallSettings)"/>,
 /// but the entire batch is not executed atomically.
 /// </summary>
 /// <remarks>
 /// <para>
 /// This method simply delegates to <see cref="MutateRowsAsync(MutateRowsRequest, CallSettings)"/>.
 /// </para>
 /// </remarks>
 /// <param name="tableName">
 /// The unique name of the table to which the mutations should be applied. Must not be null.
 /// </param>
 /// <param name="entries">
 /// The row keys and corresponding mutations to be applied in bulk.
 /// Each entry is applied as an atomic mutation, but the entries may be
 /// applied in arbitrary order (even between entries for the same row).
 /// At least one entry must be specified, and in total the entries can
 /// contain at most 100000 mutations. Must not be null, or contain null
 /// elements.
 /// </param>
 /// <param name="callSettings">
 /// If not null, applies overrides to this RPC call.
 /// </param>
 /// <returns>
 /// The response from mutating the rows.
 /// </returns>
 public virtual Task <MutateRowsResponse> MutateRowsAsync(
     TableName tableName,
     IEnumerable <MutateRowsRequest.Types.Entry> entries,
     CallSettings callSettings = null) =>
 MutateRowsAsync(CreateMutateRowRequest(tableName, entries), callSettings);
Example #34
0
 /// <summary>
 /// Rolls back this transaction.
 /// </summary>
 /// <remarks>This method is rarely useful explicitly; the <see cref="Dispose"/> method rolls back the transaction if it
 /// is still active, so a <c>using</c> statement is normally preferable to this.</remarks>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <exception cref="InvalidOperationException">The transaction has already been committed or rolled back.</exception>
 public virtual RollbackResponse Rollback(CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
        public void MatchPartiesInABatch()
        {
            var invitesList = new List <string>();
            // Create three parties with a different amount of members. The first one is a solo party, the rest have two
            // and three members respectively.
            var leaderIds         = new List <string>();
            var leaderIdToMembers = new Dictionary <string, List <string> >();
            var playerPits        = new Dictionary <string, string>();

            for (var partyCount = 1; partyCount <= 3; partyCount++)
            {
                var leaderId  = $"leader_{partyCount}";
                var leaderPit = CreatePlayerIdentityTokenForPlayer(leaderId);
                playerPits[leaderId] = leaderPit;
                var partyId = _partyClient.CreateParty(new CreatePartyRequest(),
                                                       new Metadata {
                    { PitRequestHeaderName, leaderPit }
                }).PartyId;

                for (var memberCount = 1; memberCount < partyCount; memberCount++)
                {
                    var memberId            = $"member_{partyCount}_{memberCount}";
                    var memberPit           = CreatePlayerIdentityTokenForPlayer(memberId);
                    var inviteAnotherPlayer = _inviteClient.CreateInvite(new CreateInviteRequest {
                        ReceiverPlayerId = memberId
                    },
                                                                         new Metadata {
                        { PitRequestHeaderName, leaderPit }
                    }).InviteId;
                    Assert.NotNull(inviteAnotherPlayer);
                    invitesList.Add(inviteAnotherPlayer);

                    leaderIdToMembers.TryAdd(leaderId, new List <string>());
                    leaderIdToMembers[leaderId].Add(memberId);
                    playerPits[memberId] = memberPit;
                    _partyClient.JoinParty(new JoinPartyRequest {
                        PartyId = partyId
                    },
                                           new Metadata {
                        { PitRequestHeaderName, memberPit }
                    });
                }
            }

            // The three leaders perform a Join request for their parties.
            foreach (var leaderId in leaderIds)
            {
                _gatewayClient.Join(new JoinRequest
                {
                    MatchmakingType = "match3"
                }, new Metadata {
                    { PitRequestHeaderName, playerPits[leaderId] }
                });
            }

            AssertWithinSeconds(20, () =>
            {
                foreach (var leaderId in leaderIds)
                {
                    var leaderPit = playerPits[leaderId];
                    var leaderOp  = _operationsClient.GetOperation(leaderId,
                                                                   CallSettings.FromHeader(PitRequestHeaderName, leaderPit));
                    if (!leaderOp.Done)
                    {
                        return(false);
                    }

                    // If the matchmaking op is done for the leader, other members' ops should also be completed.
                    var partyOps = new List <Operation> {
                        leaderOp
                    };
                    foreach (var memberId in leaderIdToMembers[leaderId])
                    {
                        if (memberId == leaderId)
                        {
                            continue;
                        }

                        var memberOp = _operationsClient.GetOperation(memberId,
                                                                      CallSettings.FromHeader(PitRequestHeaderName, playerPits[memberId]));
                        if (!memberOp.Done)
                        {
                            Assert.Fail(
                                $"The leader has finalized matchmaking but one of the members ({memberId}) has not");
                            return(false);
                        }

                        partyOps.Add(memberOp);
                    }

                    // None of the members should have gotten an Error code.
                    foreach (var op in partyOps)
                    {
                        if (op.Error != null)
                        {
                            Assert.Fail($"Op returned error code: {op.Error.Code}");
                            return(false);
                        }
                    }

                    // All members of the party should have the same deployment info as the leader. Their login tokens
                    // should have been generated.
                    var leaderDeployment = leaderOp.Response.Unpack <JoinResponse>().DeploymentName;
                    foreach (var op in partyOps)
                    {
                        var joinResponse = op.Response.Unpack <JoinResponse>();
                        Assert.AreEqual(leaderDeployment, joinResponse.DeploymentName);
                        Assert.False(string.IsNullOrEmpty(joinResponse.LoginToken));
                    }
                }

                return(true);
            });

            // Delete the three parties which have been created.
            foreach (var leaderId in leaderIds)
            {
                _partyClient.DeleteParty(new DeletePartyRequest(),
                                         new Metadata {
                    { PitRequestHeaderName, playerPits[leaderId] }
                });
            }
        }
        public void WithCallTiming_NullTiming()
        {
            CallTiming timing = CallTiming.FromExpiration(Expiration.None);
            CancellationToken token = new CancellationTokenSource().Token;

            var original = new CallSettings(token, null, timing, null, null, null);
            var result = original.WithCallTiming(null);
            Assert.Null(result.Timing);
            Assert.Equal(token, result.CancellationToken);
        }
Example #37
0
 /// <summary>
 /// Rolls back this transaction asynchronously.
 /// </summary>
 /// <remarks>This method is rarely useful explicitly; the <see cref="Dispose"/> method rolls back the transaction if it
 /// is still active, so a <c>using</c> statement is normally preferable to this.</remarks>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <exception cref="InvalidOperationException">The transaction has already been committed or rolled back.</exception>
 public virtual Task <RollbackResponse> RollbackAsync(CallSettings callSettings = null)
 {
     throw new NotImplementedException();
 }
Example #38
0
 /// <summary>
 /// Runs the given query eagerly in this transaction, retrieving all results in memory and indicating whether more
 /// results may be available beyond the query's limit. Use this method when your query has a limited
 /// number of results, for example to build a web application which fetches results in pages.
 /// </summary>
 /// <remarks>
 /// <para>
 /// Using a transaction ensures that a commit operation will fail if any of the entities returned
 /// by this query have been modified while the transaction is active. Note that modifications performed
 /// as part of this operation are not reflected in the query results.
 /// </para>
 /// <para>The default implementation of this method delegates to <see cref="RunQueryLazily(Query, CallSettings)"/>
 /// and calls <see cref="LazyDatastoreQuery.GetAllResults"/> on the return value.</para>
 /// </remarks>
 /// <param name="query">The query to execute. Must not be null.</param>
 /// <param name="callSettings">If not null, applies overrides to RPC calls.</param>
 /// <returns>The complete query results.</returns>
 public virtual DatastoreQueryResults RunQuery(Query query, CallSettings callSettings = null) =>
 RunQueryLazily(query, callSettings).GetAllResults();
Example #39
0
 partial void Modify_RunQueryRequest(ref RunQueryRequest request, ref CallSettings settings)
 {
     settings = settings.WithHeader(ResourcePrefixHeader, "projects/" + request.ProjectId);
 }