public RedisIndex(RedisTableCache parent, string indexKey, SearchConditions searchConditions) { this._parent = parent; this.IndexKeyInCache = indexKey; this._searchConditions = searchConditions; try { // (re)registering it in the list of indexes (it should be visible for update operations) this._parent._redis.SetHashWithRetries(this._parent.GetIndexListKeyInCache(), this.IndexKeyInCache, this._searchConditions.ToRedisValue()); // asynchronously checking the total number of indexes Task.Run(() => this.TryKeepIndexListSlim(indexKey)); // creating an index and marking it as being rebuilt this._parent._redis.CreateNewHashWithRetries(this.IndexKeyInCache, IndexVersionField.Name, IndexVersionField.IsBeingRebuiltValue); this.RedisTransaction = this._parent._redis.BeginTransaction(IndexVersionField.IsBeingRebuiltCondition(this.IndexKeyInCache)); this._parent.Log("Index ({0}) was marked as being rebuilt", this._searchConditions.Key); } catch (Exception ex) { this._parent.Log("Failed to start creating index: {0}", ex); // if something goes wrong - dropping the index (but only from the list - we don't want to let parallel update transaction to fail) this._parent._redis.RemoveHashFieldsWithRetries(this._parent.GetIndexListKeyInCache(), this.IndexKeyInCache); throw; } }
/// <summary> /// Loads all entities from an index or throws, if something wasn't found /// </summary> public static Document[] LoadProjectionIndexEntities(RedisWrapper redis, string indexKey, string indexListKey) { var rawIndex = redis.GetHashFieldsWithRetries(indexKey); if (rawIndex.Length <= 0) { redis.RemoveHashFieldsWithRetries(indexListKey, indexKey); throw new RedisCacheException("Index wasn't found in cache"); } var indexVersionField = new IndexVersionField(); var wrappers = ( from hashField in rawIndex where !indexVersionField.TryInitialize(hashField) select hashField.Value.ToObject <CacheDocumentWrapper>() ) .ToList(); // if the index is being rebuilt if (indexVersionField.IsIndexBeingRebuilt) { throw new RedisCacheException("Index is being rebuilt"); } return(wrappers.Select(w => w.Document).ToArray()); }
/// <summary> /// Loads all entities from an index or throws, if something wasn't found /// </summary> public static Document[] LoadIndexEntities(RedisWrapper redis, string indexKey, string indexListKey) { var rawIndex = redis.GetHashFieldsWithRetries(indexKey); if (rawIndex.Length <= 0) { redis.RemoveHashFieldsWithRetries(indexListKey, indexKey); throw new RedisCacheException("Index wasn't found in cache"); } var indexVersionField = new IndexVersionField(); var entityKeys = ( from hashField in rawIndex where !indexVersionField.TryInitialize(hashField) select hashField.Name.ToEntityKey() ) .ToList(); // if the index is being rebuilt if (indexVersionField.IsIndexBeingRebuilt) { throw new RedisCacheException("Index is being rebuilt"); } try { var wrappers = redis.GetWithRetries <CacheDocumentWrapper>(entityKeys.Select(k => k.ToRedisKey()).ToArray()); return(wrappers.Select(w => w.Document).ToArray()); } catch (Exception) { // if failed to load all entities - dropping the index redis.RemoveHashFieldsWithRetries(indexListKey, indexKey); redis.RemoveWithRetries(indexKey); throw; } }