public async Task <ILiveResult <TResult> > Execute <TQuery, TResult>(TQuery query, QueryOptions options = null) where TQuery : IQuery <TModel, TResult> where TResult : class { var schema = _querySchemaRegister.GetByQueryType(typeof(TQuery)); var projectionSchema = _projectionSchemaRegister.FindByModelType(typeof(TModel)); var queryHandler = _serviceProvider.GetRequiredService <IQueryHandler <TQuery, TModel, TResult> >(); var queryParitioner = GetQueryPartitioner <TQuery, TResult>(); var partitionId = queryParitioner?.CalculatePartition(query); LiveQuery <TQuery, TModel, TResult> liveQuery = new LiveQuery <TQuery, TModel, TResult>(query, partitionId, queryHandler, schema, OnQueryDispose, options); var streamInfo = _partitions.GetOrAdd(partitionId.HasValue ? partitionId.Value : _rootPartitionId, pid => new DataPartitionStream <TModel>(pid, this, _subscriptionController, projectionSchema, !partitionId.HasValue)); await streamInfo.Catchup(); streamInfo.AppendQuery(liveQuery); _liveQueries.TryAdd(liveQuery.Query, liveQuery); // HACK if (liveQuery.Options.ExpectNotNull) { while (liveQuery.Result == null) { liveQuery.Load(GetModel()); await Task.Delay(100); } } return(liveQuery); }
public void AppendQuery <TQuery, TResult>(LiveQuery <TQuery, TModel, TResult> liveQuery) where TQuery : IQuery <TModel, TResult> where TResult : class { if (_associatedQueries.TryAdd(liveQuery.Query, liveQuery)) { // this might fail - projection might not yet processed all the events. liveQuery.Load(_engine.GetModel()); } }