Exemple #1
0
        /// <summary>
        /// Loads the specified entity with the specified id.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public T Load <T>(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id", "The document id cannot be null");
            }
            object existingEntity;

            if (entitiesByKey.TryGetValue(id, out existingEntity))
            {
                return((T)existingEntity);
            }

            IncrementRequestCount();
            var  loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, id);
            bool retry;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    retry = loadOperation.SetResult(DatabaseCommands.Get(id));
                }
            } while (retry);
            return(loadOperation.Complete <T>());
        }
        public T[] LoadInternal <T>(string[] ids, KeyValuePair <string, Type>[] includes)
        {
            if (ids.Length == 0)
            {
                return(new T[0]);
            }

            if (CheckIfIdAlreadyIncluded(ids, includes))
            {
                return(ids.Select(Load <T>).ToArray());
            }
            var includePaths = includes != null?includes.Select(x => x.Key).ToArray() : null;


            IncrementRequestCount();
            var        loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, ids, includes);
            LoadResult loadResult;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    loadResult = DatabaseCommands.Get(ids, includePaths);
                }
            } while (loadOperation.SetResult(loadResult));

            return(loadOperation.Complete <T>());
        }
        public Task <T> LoadAsync <T>(string id)
        {
            object existingEntity;

            if (entitiesByKey.TryGetValue(id, out existingEntity))
            {
                return(CompletedTask.With((T)existingEntity));
            }

            IncrementRequestCount();
            var shardRequestData = new ShardRequestData
            {
                EntityType = typeof(T),
                Keys       = { id }
            };

            var dbCommands = GetCommandsToOperateOn(shardRequestData);
            var results    = shardStrategy.ShardAccessStrategy.ApplyAsync(dbCommands, shardRequestData, (commands, i) =>
            {
                var loadOperation = new LoadOperation(this, commands.DisableAllCaching, id);

                Func <Task> executer = null;
                executer             = () =>
                {
                    loadOperation.LogOperation();

                    var loadContext = loadOperation.EnterLoadContext();
                    return(commands.GetAsync(id).ContinueWith(task =>
                    {
                        if (loadContext != null)
                        {
                            loadContext.Dispose();
                        }

                        if (loadOperation.SetResult(task.Result))
                        {
                            return executer();
                        }
                        return new CompletedTask();
                    }).Unwrap());
                };
                return(executer().ContinueWith(_ =>
                {
                    _.AssertNotFailed();
                    return loadOperation.Complete <T>();
                }));
            });

            return(results.ContinueWith(task =>
            {
                var shardsContainThisDocument = task.Result.Where(x => !Equals(x, default(T))).ToArray();
                if (shardsContainThisDocument.Count() > 1)
                {
                    throw new InvalidOperationException("Found document with id: " + id +
                                                        " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide.");
                }

                return shardsContainThisDocument.FirstOrDefault();
            }));
        }
        public T[] LoadInternal <T>(string[] ids)
        {
            if (ids.Length == 0)
            {
                return(new T[0]);
            }

            // only load documents that aren't already cached
            var idsOfNotExistingObjects = ids.Where(id => IsLoaded(id) == false && IsDeleted(id) == false)
                                          .Distinct(StringComparer.OrdinalIgnoreCase)
                                          .ToArray();

            if (idsOfNotExistingObjects.Length > 0)
            {
                IncrementRequestCount();
                var        loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, idsOfNotExistingObjects, null);
                LoadResult loadResult;
                do
                {
                    loadOperation.LogOperation();
                    using (loadOperation.EnterLoadContext())
                    {
                        loadResult = DatabaseCommands.Get(idsOfNotExistingObjects, null);
                    }
                } while (loadOperation.SetResult(loadResult));

                loadOperation.Complete <T>();
            }

            return(ids.Select(Load <T>).ToArray());
        }
Exemple #5
0
        /// <summary>
        /// Begins the async load operation
        /// </summary>
        public async Task <T[]> LoadAsyncInternal <T>(string[] ids, CancellationToken token = default(CancellationToken))
        {
            if (ids.Length == 0)
            {
                return(new T[0]);
            }

            // only load documents that aren't already cached
            var idsOfNotExistingObjects = ids.Where(id => IsLoaded(id) == false && IsDeleted(id) == false)
                                          .Distinct(StringComparer.OrdinalIgnoreCase)
                                          .ToArray();

            if (idsOfNotExistingObjects.Length > 0)
            {
                IncrementRequestCount();
                var        loadOperation = new LoadOperation(this, AsyncDatabaseCommands.DisableAllCaching, idsOfNotExistingObjects, null);
                LoadResult loadResult;
                do
                {
                    loadOperation.LogOperation();
                    using (loadOperation.EnterLoadContext())
                    {
                        loadResult = await AsyncDatabaseCommands.GetAsync(idsOfNotExistingObjects, null).ConfigureAwait(false);
                    }
                } while (loadOperation.SetResult(loadResult));

                loadOperation.Complete <T>();
            }

            var loadTasks  = ids.Select(async id => await LoadAsync <T>(id, token).ConfigureAwait(false)).ToArray();
            var loadedData = await Task.WhenAll(loadTasks).WithCancellation(token).ConfigureAwait(false);

            return(loadedData);
        }
Exemple #6
0
        /// <summary>
        /// Begins the async load operation
        /// </summary>
        public async Task <T[]> LoadAsyncInternal <T>(string[] ids, KeyValuePair <string, Type>[] includes, CancellationToken token = default(CancellationToken))
        {
            if (CheckIfIdAlreadyIncluded(ids, includes))
            {
                var loadTasks  = ids.Select(id => LoadAsync <T>(id, token)).ToArray();
                var loadedData = await Task.WhenAll(loadTasks).WithCancellation(token).ConfigureAwait(false);

                return(loadedData);
            }

            IncrementRequestCount();
            var loadOperation = new LoadOperation(this, AsyncDatabaseCommands.DisableAllCaching, ids, includes);

            loadOperation.LogOperation();
            var includePaths = includes != null?includes.Select(x => x.Key).ToArray() : null;

            LoadResult result;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    result = await AsyncDatabaseCommands.GetAsync(ids, includePaths, token : token).ConfigureAwait(false);
                }
            } while (loadOperation.SetResult(result));
            return(loadOperation.Complete <T>());
        }
        public T Load <T>(string id)
        {
            if (IsDeleted(id))
            {
                return(default(T));
            }

            object existingEntity;

            if (entitiesByKey.TryGetValue(id, out existingEntity))
            {
                return((T)existingEntity);
            }
            JsonDocument value;

            if (includedDocumentsByKey.TryGetValue(id, out value))
            {
                includedDocumentsByKey.Remove(id);
                return(TrackEntity <T>(value));
            }
            IncrementRequestCount();
            var shardRequestData = new ShardRequestData
            {
                EntityType = typeof(T),
                Keys       = { id }
            };
            var dbCommands = GetCommandsToOperateOn(shardRequestData);
            var results    = shardStrategy.ShardAccessStrategy.Apply(dbCommands, shardRequestData, (commands, i) =>
            {
                var loadOperation = new LoadOperation(this, commands.DisableAllCaching, id);
                bool retry;
                do
                {
                    loadOperation.LogOperation();
                    using (loadOperation.EnterLoadContext())
                    {
                        retry = loadOperation.SetResult(commands.Get(id));
                    }
                } while (retry);
                return(loadOperation.Complete <T>());
            });

            var shardsContainThisDocument = results.Where(x => !Equals(x, default(T))).ToArray();

            if (shardsContainThisDocument.Count() > 1)
            {
                throw new InvalidOperationException("Found document with id: " + id +
                                                    " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide.");
            }

            return(shardsContainThisDocument.FirstOrDefault());
        }
Exemple #8
0
        private async Task <T> CompleteLoadAsync <T>(string id, LoadOperation loadOperation, CancellationToken token = default(CancellationToken))
        {
            loadOperation.LogOperation();
            using (loadOperation.EnterLoadContext())
            {
                var result = await AsyncDatabaseCommands.GetAsync(id, token);

                if (loadOperation.SetResult(result) == false)
                {
                    return(loadOperation.Complete <T>());
                }

                return(await CompleteLoadAsync <T>(id, loadOperation, token).WithCancellation(token));
            }
        }
        private Task <T> CompleteLoadAsync <T>(string id, LoadOperation loadOperation)
        {
            loadOperation.LogOperation();
            using (loadOperation.EnterLoadContext())
            {
                return(AsyncDatabaseCommands.GetAsync(id)
                       .ContinueWith(task =>
                {
                    if (loadOperation.SetResult(task.Result) == false)
                    {
                        return Task.Factory.StartNew(() => loadOperation.Complete <T>());
                    }

                    return CompleteLoadAsync <T>(id, loadOperation);
                })
                       .Unwrap());
            }
        }
        /// <summary>
        /// Loads the specified entity with the specified id.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public T Load <T>(string id)
        {
            if (id == null)
            {
                throw new ArgumentNullException("id", "The document id cannot be null");
            }
            if (IsDeleted(id))
            {
                return(default(T));
            }
            object existingEntity;

            if (EntitiesById.TryGetValue(id, out existingEntity))
            {
                return((T)existingEntity);
            }
            JsonDocument value;

            if (includedDocumentsByKey.TryGetValue(id, out value))
            {
                includedDocumentsByKey.Remove(id);
                return(TrackEntity <T>(value));
            }

            IncrementRequestCount();
            var  loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, id);
            bool retry;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    retry = loadOperation.SetResult(DatabaseCommands.Get(id));
                }
            } while (retry);
            return(loadOperation.Complete <T>().FirstOrDefault());
        }
Exemple #11
0
        /// <summary>
        /// Loads the specified entity with the specified id.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="id">The id.</param>
        /// <returns></returns>
        public T Load <T>(string id)
        {
            object existingEntity;

            if (entitiesByKey.TryGetValue(id, out existingEntity))
            {
                return((T)existingEntity);
            }

            IncrementRequestCount();
            var  loadOperation = new LoadOperation(this, DatabaseCommands.DisableAllCaching, id);
            bool retry;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    retry = loadOperation.SetResult(DatabaseCommands.Get(id));
                }
            } while (retry);
            return(loadOperation.Complete <T>());
        }
        public static async Task <T[]> MoreLikeThisAsync <T>(this IAsyncAdvancedSessionOperations advancedSession, string index, string transformer, MoreLikeThisQuery parameters)
        {
            if (string.IsNullOrEmpty(index))
            {
                throw new ArgumentException("Index name cannot be null or empty", "index");
            }

            parameters.IndexName   = index;
            parameters.Transformer = transformer;

            // /morelikethis/(index-name)/(ravendb-document-id)?fields=(fields)
            var cmd = ((AsyncDocumentSession)advancedSession).AsyncDatabaseCommands;

            var inMemoryDocumentSessionOperations = ((InMemoryDocumentSessionOperations)advancedSession);

            inMemoryDocumentSessionOperations.IncrementRequestCount();

            var        loadOperation = new LoadOperation(inMemoryDocumentSessionOperations, cmd.DisableAllCaching, null, null);
            LoadResult loadResult;

            do
            {
                loadOperation.LogOperation();
                using (loadOperation.EnterLoadContext())
                {
                    var result = await cmd.MoreLikeThisAsync(parameters).ConfigureAwait(false);

                    loadResult = new LoadResult
                    {
                        Includes = result.Includes,
                        Results  = result.Results
                    };
                }
            } while (loadOperation.SetResult(loadResult));

            return(loadOperation.Complete <T>());
        }
Exemple #13
0
 public IDisposable EnterContext()
 {
     return(loadOperation.EnterLoadContext());
 }
Exemple #14
0
        public T[] LoadInternal <T>(string[] ids, KeyValuePair <string, Type>[] includes)
        {
            var results      = new T[ids.Length];
            var includePaths = includes != null?includes.Select(x => x.Key).ToArray() : null;

            var idsToLoad = GetIdsThatNeedLoading <T>(ids, includePaths, transformer: null);

            if (!idsToLoad.Any())
            {
                return(results);
            }

            IncrementRequestCount();

            foreach (var shard in idsToLoad)
            {
                var currentShardIds     = shard.Select(x => x.Id).ToArray();
                var multiLoadOperations = shardStrategy.ShardAccessStrategy.Apply(shard.Key, new ShardRequestData
                {
                    EntityType = typeof(T),
                    Keys       = currentShardIds.ToList()
                }, (dbCmd, i) =>
                {
                    var multiLoadOperation = new LoadOperation(this, dbCmd.DisableAllCaching, currentShardIds, includes);
                    LoadResult loadResult;
                    do
                    {
                        multiLoadOperation.LogOperation();
                        using (multiLoadOperation.EnterLoadContext())
                        {
                            loadResult = dbCmd.Get(currentShardIds, includePaths);
                        }
                    } while (multiLoadOperation.SetResult(loadResult));
                    return(multiLoadOperation);
                });
                foreach (var multiLoadOperation in multiLoadOperations)
                {
                    var loadResults = multiLoadOperation.Complete <T>();
                    for (int i = 0; i < loadResults.Length; i++)
                    {
                        if (ReferenceEquals(loadResults[i], null))
                        {
                            continue;
                        }
                        var id           = currentShardIds[i];
                        var itemPosition = Array.IndexOf(ids, id);
                        if (ReferenceEquals(results[itemPosition], default(T)) == false)
                        {
                            throw new InvalidOperationException("Found document with id: " + id +
                                                                " on more than a single shard, which is not allowed. Document keys have to be unique cluster-wide.");
                        }
                        results[itemPosition] = loadResults[i];
                    }
                }
            }
            return(ids.Select(id => // so we get items that were skipped because they are already in the session cache
            {
                object val;
                EntitiesById.TryGetValue(id, out val);
                return (T)val;
            }).ToArray());
        }