/// <summary> /// Executes a <see cref="IViewQuery"/> asynchronously against a View. /// </summary> /// <typeparam name="T">The Type parameter of the result returned by the query.</typeparam> /// <param name="query">The <see cref="IViewQuery"/> to execute on.</param> /// <returns>A <see cref="Task{T}"/> that can be awaited on for the results.</returns> public async Task <IViewResult <T> > ExecuteAsync <T>(IViewQuery query) { IViewResult <T> viewResult = new ViewResult <T>(); try { var result = await HttpClient.GetAsync(query.RawUri()); var content = result.Content; var stream = await content.ReadAsStreamAsync(); viewResult = Mapper.Map <ViewResult <T> >(stream); viewResult.Success = result.IsSuccessStatusCode; viewResult.StatusCode = result.StatusCode; } catch (AggregateException ae) { ae.Flatten().Handle(e => { Log.Error(e); return(true); }); } return(viewResult); }
/// <summary> /// Executes an <see cref="IViewQuery"/> asynchronously. If it fails, the response is checked and /// if certain criteria are met the request is retried until it times out. /// </summary> /// <typeparam name="T">The Type of View result body.</typeparam> /// <param name="execute">A delegate with the send logic that is executed on each attempt. </param> /// <param name="query">The <see cref="IViewQuery"/> to execute.</param> /// <param name="configInfo">The <see cref="IConfigInfo"/> that represents the logical topology of the cluster.</param> /// <param name="cancellationToken">For canceling the async operation.</param> /// <returns>A <see cref="Task{IViewResult}"/> object representing the asynchronous operation.</returns> static async Task <IViewResult <T> > RetryViewEveryAsync <T>(Func <IViewQuery, IConfigInfo, Task <IViewResult <T> > > execute, IViewQuery query, IConfigInfo configInfo, CancellationToken cancellationToken) { while (true) { var result = await execute(query, configInfo).ContinueOnAnyContext(); if (query.RetryAttempts++ >= configInfo.ClientConfig.MaxViewRetries || result.Success || result.CannotRetry()) { return(result); } Log.Debug(m => m("trying again: {0}", query.RetryAttempts)); var sleepTime = (int)Math.Pow(2, query.RetryAttempts); var task = Task.Delay(sleepTime, cancellationToken).ContinueOnAnyContext(); try { await task; } catch (TaskCanceledException) { return(result); } } }
/// <summary> /// Sends a View request with retry. /// </summary> /// <typeparam name="T">The Type T of the <see cref="ViewRow{T}"/> value.</typeparam> /// <param name="viewQuery">The view query.</param> /// <returns>A <see cref="IViewResult{T}"/> with the results of the query.</returns> public override IViewResult <T> SendWithRetry <T>(IViewQuery viewQuery) { IViewResult <T> viewResult = null; try { do { var server = ConfigInfo.GetServer(); viewResult = server.Send <T>(viewQuery); } while ( !viewResult.Success && !viewResult.CannotRetry() && viewQuery.RetryAttempts++ <= ConfigInfo.ClientConfig.MaxViewRetries); } catch (Exception e) { Log.Info(e); const string message = "View request failed, check Error and Exception fields for details."; viewResult = new ViewResult <T> { Message = message, Error = e.Message, StatusCode = HttpStatusCode.BadRequest, Success = false, Exception = e }; } return(viewResult); }
/// <summary> /// Sends a View request to the server to be executed using async/await /// </summary> /// <typeparam name="T">The Type of the body of the Views return value or row.</typeparam> /// <param name="query">An <see cref="IViewQuery" /> to be executed.</param> /// <returns> /// The result of the View request as an <see cref="Task{IViewResult}" /> to be awaited on where T is the Type of each row. /// </returns> public override async Task <IViewResult <T> > SendWithRetryAsync <T>(IViewQuery query) { IViewResult <T> viewResult = null; try { using (var cancellationTokenSource = new CancellationTokenSource(ConfigInfo.ClientConfig.ViewHardTimeout)) { var task = RetryViewEveryAsync(async(e, c) => { var server = c.GetServer(); return(await server.SendAsync <T>(query)); }, query, ConfigInfo, cancellationTokenSource.Token).ConfigureAwait(false); viewResult = await task; } } catch (Exception e) { Log.Info(e); const string message = "View request failed, check Error and Exception fields for details."; viewResult = new ViewResult <T> { Message = message, Error = e.Message, StatusCode = HttpStatusCode.BadRequest, Success = false, Exception = e }; } return(viewResult); }
public IViewResult <T> Send <T>(IViewQuery query) { var baseUri = GetBaseViewUri(query.BucketName); query.BaseUri(baseUri); return(ViewClient.Execute <T>(query)); }
/// <summary> /// Executes a <see cref="IViewQuery"/> synchronously against a View. /// </summary> /// <typeparam name="T">The Type parameter of the result returned by the query.</typeparam> /// <param name="query">The <see cref="IViewQuery"/> to execute on.</param> /// <returns>The <see cref="IViewResult{T}"/> instance which is the results of the query.</returns> public IViewResult <T> Execute <T>(IViewQuery query) { var viewResult = new ViewResult <T>(); try { var requestAwaiter = HttpClient.GetAsync(query.RawUri()).ConfigureAwait(false).GetAwaiter(); var request = requestAwaiter.GetResult(); var responseAwaiter = request.Content.ReadAsStreamAsync().ConfigureAwait(false).GetAwaiter(); var response = responseAwaiter.GetResult(); viewResult = Mapper.Map <ViewResult <T> >(response); viewResult.Success = request.IsSuccessStatusCode; viewResult.StatusCode = request.StatusCode; } catch (AggregateException ae) { ae.Flatten().Handle(e => { ProcessError(e, viewResult); Log.Error(e); return(true); }); } catch (HttpRequestException e) { ProcessError(e, viewResult); Log.Error(e); } return(viewResult); }
/// <summary> /// Executes a <see cref="IViewQuery"/> synchronously against a View. /// </summary> /// <typeparam name="T">The Type parameter of the result returned by the query.</typeparam> /// <param name="query">The <see cref="IViewQuery"/> to execute on.</param> /// <returns>The <see cref="IViewResult{T}"/> instance which is the results of the query.</returns> public IViewResult <T> Execute <T>(IViewQuery query) { IViewResult <T> viewResult = new ViewResult <T>(); var task = HttpClient.GetAsync(query.RawUri()); try { task.Wait(); var result = task.Result; var content = result.Content; var stream = content.ReadAsStreamAsync(); stream.Wait(); viewResult = Mapper.Map <ViewResult <T> >(stream.Result); viewResult.Success = result.IsSuccessStatusCode; viewResult.StatusCode = result.StatusCode; } catch (AggregateException ae) { ae.Flatten().Handle(e => { ProcessError(e, viewResult); Log.Error(e); return(true); }); } return(viewResult); }
public View(IDbConnection connection, ISQLConfiguration configuration, Assembly assembly, IViewQuery <V> viewQuery) { this.connection = connection; this.configuration = configuration; this.assembly = assembly; this.viewQuery = viewQuery; }
/// <summary> /// Sends a request for a View to the server asynchronously. /// </summary> /// <typeparam name="T">The <see cref="Type" /> T of the body for each row result.</typeparam> /// <param name="query">The <see cref="IViewQuery" /> representing the query.</param> /// <returns> /// An <see cref="Task{IViewResult}" /> object representing the asynchronous operation. /// </returns> public Task <IViewResult <T> > SendAsync <T>(IViewQuery query) { Task <IViewResult <T> > result; try { var baseUri = GetBaseViewUri(query.BucketName); query.BaseUri(baseUri); result = ViewClient.ExecuteAsync <T>(query); } catch (Exception e) { var tcs = new TaskCompletionSource <IViewResult <T> >(); tcs.SetResult(new ViewResult <T> { Exception = e, Message = e.Message, Error = e.Message, Success = false, StatusCode = HttpStatusCode.BadRequest, Rows = new List <ViewRow <T> >() }); result = tcs.Task; } return(result); }
/// <summary> /// Executes a <see cref="IViewQuery"/> asynchronously against a View. /// </summary> /// <typeparam name="T">The Type parameter of the result returned by the query.</typeparam> /// <param name="query">The <see cref="IViewQuery"/> to execute on.</param> /// <returns>A <see cref="Task{T}"/> that can be awaited on for the results.</returns> public async Task <IViewResult <T> > ExecuteAsync <T>(IViewQuery query) { var uri = query.RawUri(); var viewResult = new ViewResult <T>(); try { var result = await HttpClient.GetAsync(uri).ConfigureAwait(false); var content = result.Content; using (var stream = await content.ReadAsStreamAsync().ConfigureAwait(false)) { viewResult = Mapper.Map <ViewResult <T> >(stream); viewResult.Success = result.IsSuccessStatusCode; viewResult.StatusCode = result.StatusCode; viewResult.Message = Success; } } catch (AggregateException ae) { ae.Flatten().Handle(e => { ProcessError(e, viewResult); Log.Error(uri, e); return(true); }); } catch (TaskCanceledException e) { const string error = "The request has timed out."; ProcessError(e, error, viewResult); Log.Error(uri, e); } return(viewResult); }
public async Task <IViewResult <T> > Query <T>(IViewQuery query) { using (var bucket = await cluster.OpenBucketAsync(this.Options.Value.Bucket)) { return(await bucket.QueryAsync <T>(query)); } }
public virtual async Task <ViewQueryResponse <T> > RunQueryAsync <T>(IViewQuery query) where T : class { EnsureValidQuery(query); var req = CreateRequest(query); var res = SendAsync(req); return(ProcessHttpResponse <T>(await res.ForAwait())); }
public virtual async Task <JsonViewQueryResponse> RunQueryAsync(IViewQuery query) { EnsureValidQuery(query); var req = CreateRequest(query); var res = SendAsync(req); return(ProcessHttpResponse(await res.ForAwait())); }
private IRequestSpan RootSpan(string operation, IViewQuery query) { var span = _tracer.RequestSpan(operation, query.RequestSpanValue); span.SetAttribute(OuterRequestSpans.Attributes.System.Key, OuterRequestSpans.Attributes.System.Value); span.SetAttribute(OuterRequestSpans.Attributes.Service, nameof(OuterRequestSpans.ServiceSpan.ViewQuery).ToLowerInvariant()); span.SetAttribute(OuterRequestSpans.Attributes.BucketName, query.BucketName !); span.SetAttribute(OuterRequestSpans.Attributes.Operation, operation); return(span); }
public IEnumerable <T> Select(IViewQuery viewQuery) { var results = Bucket.Query <T>(viewQuery); if (!results.Success) { var message = results.Error; throw new ViewRequestException(message, results.StatusCode); } return(results.Values); }
internal static IRequestSpan DispatchSpan(this IRequestSpan parentSpan, IViewQuery viewQuery) { var childSpan = DispatchSpan(parentSpan); if (childSpan.CanWrite) { childSpan.SetAttribute(InnerRequestSpans.DispatchSpan.Attributes.OperationId, viewQuery.ClientContextId ?? Guid.NewGuid().ToString()); } return(childSpan); }
public override IEnumerable <KeyValuePair <long, Tick> > Read() { IBucket bucket = buckets[0]; IViewQuery query = bucket.CreateQuery(DocDesignName, ViewName, false).Asc(); foreach (var item in buckets[0].Query <dynamic>(query).Rows) { long key = Int64.Parse(item.Key.ToString()); Tick record = item.Value; yield return(new KeyValuePair <long, Tick>(key, record)); } }
private IRequestSpan RootSpan(string operation, IViewQuery query) { var span = _tracer.RequestSpan(operation, query.RequestSpanValue); if (span.CanWrite) { span.SetAttribute(OuterRequestSpans.Attributes.System.Key, OuterRequestSpans.Attributes.System.Value); span.SetAttribute(OuterRequestSpans.Attributes.Service, OuterRequestSpans.ServiceSpan.ViewQuery); span.SetAttribute(OuterRequestSpans.Attributes.BucketName, query.BucketName !); span.SetAttribute(OuterRequestSpans.Attributes.Operation, operation); } return(span); }
protected virtual string GenerateRequestUrl(IViewQuery query) { if (query is ISystemViewQuery) { return(string.Format("{0}/{1}?{2}", Connection.Address, query.View.Name, GenerateQueryStringParams(query.Options))); } return(string.Format("{0}/_design/{1}/_view/{2}?{3}", Connection.Address, query.View.DesignDocument, query.View.Name, GenerateQueryStringParams(query.Options))); }
/// <summary> /// Executes a <see cref="IViewQuery"/> synchronously against a View. /// </summary> /// <typeparam name="T">The Type parameter of the result returned by the query.</typeparam> /// <param name="query">The <see cref="IViewQuery"/> to execute on.</param> /// <returns>The <see cref="IViewResult{T}"/> instance which is the results of the query.</returns> public IViewResult <T> Execute <T>(IViewQuery query) { var viewResult = new ViewResult <T>(); try { var request = WebRequest.Create(query.RawUri()); request.Timeout = _clientConfig.ViewRequestTimeout; WriteAuthenticationHeaders(request, _bucketConfig.Name, _bucketConfig.Password); using (var response = request.GetResponse() as HttpWebResponse) { var stream = response.GetResponseStream(); viewResult = Mapper.Map <ViewResult <T> >(stream); response.Close(); viewResult.Success = response.StatusCode == HttpStatusCode.OK; viewResult.StatusCode = response.StatusCode; } } catch (WebException e) { if (e.Response != null) { var stream = e.Response.GetResponseStream(); viewResult = Mapper.Map <ViewResult <T> >(stream); } viewResult.Exception = e; viewResult.StatusCode = GetStatusCode(e.Message); Log.Error(e); } catch (Exception e) { ProcessError(e, viewResult); Log.Error(e); } return(viewResult); }
public IViewResult <T> Send <T>(IViewQuery query) { IViewResult <T> result; try { var baseUri = GetBaseViewUri(query.BucketName); query.BaseUri(baseUri); result = ViewClient.Execute <T>(query); } catch (Exception e) { result = new ViewResult <T> { Exception = e, Message = e.Message, Error = e.Message, Success = false, StatusCode = HttpStatusCode.BadRequest, Rows = new List <ViewRow <T> >() }; } return(result); }
public override void Init(int flowCount, long flowRecordCount) { buckets = new IBucket[flowCount]; ClientConfiguration client = new ClientConfiguration(); client.Servers.Add(new Uri(ConnectionString)); cluster = new Cluster(client); for (int i = 0; i < flowCount; i++) { buckets[i] = cluster.OpenBucket(CollectionName); } IBucket bucket = buckets[0]; IViewQuery query = bucket.CreateQuery(DocDesignName, ViewName, false); // TODO: find a faster way for dropping the database. foreach (var item in buckets[0].Query <dynamic>(query).Rows) { buckets[0].Remove(item.Key.ToString()); } }
/// <summary> /// Sends a View request with retry. /// </summary> /// <typeparam name="T">The Type T of the <see cref="ViewRow{T}"/> value.</typeparam> /// <param name="viewQuery">The view query.</param> /// <returns>A <see cref="IViewResult{T}"/> with the results of the query.</returns> public override IViewResult <T> SendWithRetry <T>(IViewQuery viewQuery) { //Is the cluster configured for View services? if (!ConfigInfo.IsViewCapable) { throw new ServiceNotSupportedException("The cluster does not support View services."); } IViewResult <T> viewResult = null; try { do { var server = ConfigInfo.GetViewNode(); viewResult = server.Send <T>(viewQuery); } while ( !viewResult.Success && !viewResult.CannotRetry() && viewQuery.RetryAttempts++ <= ConfigInfo.ClientConfig.MaxViewRetries); } catch (Exception e) { Log.Info(e); const string message = "View request failed, check Error and Exception fields for details."; viewResult = new ViewResult <T> { Message = message, Error = e.Message, StatusCode = HttpStatusCode.BadRequest, Success = false, Exception = e }; } return(viewResult); }
public async Task <IViewResult <T> > SendAsync <T>(IViewQuery query) { return(await ViewClient.ExecuteAsync <T>(query)); }
public IViewResult <T> Query <T>(IViewQuery query) { throw new NotImplementedException("This method is only supported on Couchbase Bucket (persistent) types."); }
public async Task <IViewResult <TKey, TValue> > ExecuteAsync <TKey, TValue>(IViewQuery query) { using var rootSpan = _tracer.RootSpan(RequestTracing.ServiceIdentifier.View, OperationNames.ViewQuery) .WithTag(CouchbaseTags.Service, RequestTracing.ServiceIdentifier.View) .WithLocalAddress(); using var encodingSpan = rootSpan.StartPayloadEncoding(); var uri = query.RawUri(); rootSpan.WithRemoteAddress(uri); ViewResultBase <TKey, TValue> viewResult; var body = query.CreateRequestBody(); try { _logger.LogDebug("Sending view request to: {uri}", _redactor.SystemData(uri)); var content = new StringContent(body, Encoding.UTF8, MediaType.Json); encodingSpan.Dispose(); using var dispatchSpan = rootSpan.StartDispatch(); var response = await HttpClient.PostAsync(uri, content).ConfigureAwait(false); dispatchSpan.Dispose(); var serializer = query.Serializer ?? _serializer; if (response.IsSuccessStatusCode) { if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer) { viewResult = new StreamingViewResult <TKey, TValue>( response.StatusCode, Success, await response.Content.ReadAsStreamAsync().ConfigureAwait(false), streamingTypeDeserializer ); } else { viewResult = new BlockViewResult <TKey, TValue>( response.StatusCode, Success, await response.Content.ReadAsStreamAsync().ConfigureAwait(false), serializer ); } await viewResult.InitializeAsync().ConfigureAwait(false); } else { if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer) { viewResult = new StreamingViewResult <TKey, TValue>( response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false), streamingTypeDeserializer ); } else { viewResult = new BlockViewResult <TKey, TValue>( response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false), serializer ); } await viewResult.InitializeAsync().ConfigureAwait(false); if (viewResult.ShouldRetry()) { UpdateLastActivity(); return(viewResult); } if (viewResult.ViewNotFound()) { throw new ViewNotFoundException(uri.ToString()) { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = response.StatusCode, Errors = viewResult.Message } }; } } } catch (OperationCanceledException e) { _logger.LogDebug(LoggingEvents.ViewEvent, e, "View request timeout."); throw new AmbiguousTimeoutException("The view query was timed out via the Token.", e) { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = HttpStatusCode.RequestTimeout } }; } catch (HttpRequestException e) { _logger.LogDebug(LoggingEvents.QueryEvent, e, "View request cancelled."); throw new RequestCanceledException("The view query was canceled.", e) { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = HttpStatusCode.RequestTimeout } }; } UpdateLastActivity(); return(viewResult); }
public async Task <IViewResult <TKey, TValue> > ExecuteAsync <TKey, TValue>(IViewQuery query) { using var rootSpan = RootSpan(OuterRequestSpans.ServiceSpan.ViewQuery, query); rootSpan.WithLocalAddress() .WithOperation(query); var uri = query.RawUri(); rootSpan.WithRemoteAddress(uri); using var encodingSpan = rootSpan.EncodingSpan(); ViewResultBase <TKey, TValue> viewResult; var body = query.CreateRequestBody(); try { _logger.LogDebug("Sending view request to: {uri}", _redactor.SystemData(uri)); var content = new StringContent(body, Encoding.UTF8, MediaType.Json); encodingSpan.Dispose(); using var dispatchSpan = rootSpan.DispatchSpan(query); using var httpClient = CreateHttpClient(); // set timeout to infinite so we can stream results without the connection // closing part way through httpClient.Timeout = Timeout.InfiniteTimeSpan; var response = await httpClient.PostAsync(uri, content).ConfigureAwait(false); dispatchSpan.Dispose(); var serializer = query.Serializer ?? _serializer; if (response.IsSuccessStatusCode) { if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer) { viewResult = new StreamingViewResult <TKey, TValue>( response.StatusCode, Success, await response.Content.ReadAsStreamAsync().ConfigureAwait(false), streamingTypeDeserializer ); } else { viewResult = new BlockViewResult <TKey, TValue>( response.StatusCode, Success, await response.Content.ReadAsStreamAsync().ConfigureAwait(false), serializer ); } await viewResult.InitializeAsync().ConfigureAwait(false); } else { if (serializer is IStreamingTypeDeserializer streamingTypeDeserializer) { viewResult = new StreamingViewResult <TKey, TValue>( response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false), streamingTypeDeserializer ); } else { viewResult = new BlockViewResult <TKey, TValue>( response.StatusCode, await response.Content.ReadAsStringAsync().ConfigureAwait(false), serializer ); } await viewResult.InitializeAsync().ConfigureAwait(false); if (viewResult.ShouldRetry()) { viewResult.NoRetryException = new CouchbaseException() { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = response.StatusCode, Errors = viewResult.Message } }; UpdateLastActivity(); return(viewResult); } if (viewResult.ViewNotFound()) { throw new ViewNotFoundException("The queried view is not found on the server.") { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = response.StatusCode, Errors = viewResult.Message } }; } } } catch (OperationCanceledException e) { //treat as an orphaned response rootSpan.LogOrphaned(); _logger.LogDebug(LoggingEvents.ViewEvent, e, "View request timeout."); throw new AmbiguousTimeoutException("The view query was timed out via the Token.", e) { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = HttpStatusCode.RequestTimeout } }; } catch (HttpRequestException e) { //treat as an orphaned response rootSpan.LogOrphaned(); _logger.LogDebug(LoggingEvents.QueryEvent, e, "View request cancelled."); throw new RequestCanceledException("The view query was canceled.", e) { Context = new ViewContextError { DesignDocumentName = query.DesignDocName, ViewName = query.ViewName, ClientContextId = query.ClientContextId, HttpStatus = HttpStatusCode.RequestTimeout } }; } UpdateLastActivity(); return(viewResult); }
protected virtual HttpRequestMessage CreateRequest(IViewQuery query) { return(new HttpRequest(HttpMethod.Get, GenerateRequestUrl(query))); }
internal static IRequestSpan WithOperation(this IRequestSpan span, IViewQuery viewQuery) { return(span.WithOperation($"{viewQuery.DesignDocName}/{viewQuery.ViewName}")); }
public Task <IViewResult <T> > QueryAsync <T>(IViewQuery query) { throw new NotSupportedException("This method is only supported on Couchbase Bucket (persistent) types."); }