Пример #1
0
        private Task <RiakResult <IEnumerable <RiakResult> > > Delete(IRiakConnection conn,
                                                                      IEnumerable <RiakObjectId> objectIds,
                                                                      RiakDeleteOptions options = null)
        {
            options = options ?? new RiakDeleteOptions();
            return(AfterAll(objectIds.Select(id => {
                if (!IsValidBucketOrKey(id.Bucket))
                {
                    return RiakResult.ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false);
                }

                if (!IsValidBucketOrKey(id.Key))
                {
                    return RiakResult.ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false);
                }

                var req = new RpbDelReq {
                    bucket = id.Bucket.ToRiakString(), key = id.Key.ToRiakString()
                };
                options.Populate(req);
                return conn.PbcWriteRead(req, MessageCode.DelResp);
            })).ContinueWith((Task <IEnumerable <RiakResult> > finishedTask) => {
                return RiakResult <IEnumerable <RiakResult> > .Success(finishedTask.Result);
            }));
        }
Пример #2
0
        public Task <RiakResult> SetBucketProperties(string bucket, RiakBucketProperties properties)
        {
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult.ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (properties.CanUsePbc)
            {
                var request = new RpbSetBucketReq {
                    bucket = bucket.ToRiakString(), props = properties.ToMessage()
                };
                return(UseConnection(conn => conn.PbcWriteRead(request, MessageCode.SetBucketResp)));
            }
            else
            {
                var request = new RiakRestRequest(ToBucketUri(bucket), RiakConstants.Rest.HttpMethod.Put)
                {
                    Body        = properties.ToJsonString().ToRiakString(),
                    ContentType = RiakConstants.ContentTypes.ApplicationJson
                };

                return(UseConnection(conn => conn.RestRequest(request))
                       .ContinueWith((Task <RiakResult <RiakRestResponse> > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess && result.Value.StatusCode != HttpStatusCode.NoContent)
                    {
                        return RiakResult.Error(ResultCode.InvalidResponse, "Unexpected Status Code: {0} ({1})".Fmt(result.Value.StatusCode, (int)result.Value.StatusCode), result.NodeOffline);
                    }
                    return result;
                }));
            }
        }
        public override Task <RiakResult <IEnumerable <TResult> > > UseDelayedConnection <TResult>(Func <IRiakConnection, Action, Task <RiakResult <IEnumerable <TResult> > > > useFun, int retryAttempts)
        {
            if (retryAttempts < 0)
            {
                return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.NoRetries, "Unable to access a connection on the cluster.", true));
            }
            if (_disposing)
            {
                return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.ShuttingDown, "System currently shutting down", true));
            }

            var node = _node;

            if (node != null)
            {
                return(node.UseDelayedConnection(useFun)
                       .ContinueWith((Task <RiakResult <IEnumerable <TResult> > > finishedTask) => {
                    var result = finishedTask.Result;
                    if (!result.IsSuccess)
                    {
                        return TaskDelay(RetryWaitTime).ContinueWith(finishedDelayTask => {
                            return UseDelayedConnection(useFun, retryAttempts - 1);
                        }).Unwrap();
                    }
                    return TaskResult(result);
                }).Unwrap());
            }
            return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.ClusterOffline, "Unable to access functioning Riak node", true));
        }
Пример #4
0
        public override Task <RiakResult <IEnumerable <TResult> > > UseDelayedConnection <TResult>(Func <IRiakConnection, Action, Task <RiakResult <IEnumerable <TResult> > > > useFun, int retryAttempts)
        {
            if (retryAttempts < 0)
            {
                return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.NoRetries, "Unable to access a connection on the cluster.", false));
            }
            if (_disposing)
            {
                return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.ShuttingDown, "System currently shutting down", true));
            }

            // select a node
            var node = _loadBalancer.SelectNode();

            if (node != null)
            {
                return(node.UseDelayedConnection(useFun)
                       .ContinueWith((Task <RiakResult <IEnumerable <TResult> > > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess)
                    {
                        return TaskResult(result);
                    }
                    else
                    {
                        if (result.ResultCode == ResultCode.NoConnections)
                        {
                            return DelayTask(RetryWaitTime)
                            .ContinueWith(delayTask => {
                                return UseDelayedConnection(useFun, retryAttempts - 1);
                            }).Unwrap();
                        }
                        if (result.ResultCode == ResultCode.CommunicationError)
                        {
                            if (result.NodeOffline)
                            {
                                DeactivateNode(node);
                            }

                            return DelayTask(RetryWaitTime)
                            .ContinueWith(delayTask => {
                                return UseDelayedConnection(useFun, retryAttempts - 1);
                            }).Unwrap();
                        }
                    }

                    // out of options
                    return RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.ClusterOffline, "Unable to access functioning Riak node", true);
                }).Unwrap());
            }

            // no functioning node
            return(RiakResult <IEnumerable <TResult> > .ErrorTask(ResultCode.ClusterOffline, "Unable to access functioning Riak node", true));
        }
Пример #5
0
        public Task <IEnumerable <RiakResult <RiakObject> > > Get(IEnumerable <RiakObjectId> bucketKeyPairs, RiakGetOptions options = null)
        {
            bucketKeyPairs = bucketKeyPairs.ToList();
            options        = options ?? new RiakGetOptions();

            return(UseConnection(conn => {
                return AfterAll(bucketKeyPairs.Select(bkp => {
                    // modified closure FTW
                    var bk = bkp;
                    if (!IsValidBucketOrKey(bk.Bucket))
                    {
                        return RiakResult <RpbGetResp> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false);
                    }
                    if (!IsValidBucketOrKey(bk.Key))
                    {
                        return RiakResult <RpbGetResp> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false);
                    }

                    var req = new RpbGetReq {
                        bucket = bk.Bucket.ToRiakString(), key = bk.Key.ToRiakString()
                    };
                    options.Populate(req);

                    return conn.PbcWriteRead <RpbGetReq, RpbGetResp>(req);
                })).ContinueWith((Task <IEnumerable <RiakResult <RpbGetResp> > > finishedTask) => {
                    return RiakResult <IEnumerable <RiakResult <RpbGetResp> > > .Success(finishedTask.Result);
                });
            }).ContinueWith((Task <RiakResult <IEnumerable <RiakResult <RpbGetResp> > > > finishedTask) => {
                // zip up results
                var results = RiakResult <IEnumerable <RiakResult <RpbGetResp> > > .Success(finishedTask.Result.Value);
                return results.Value.Zip(bucketKeyPairs, Tuple.Create).Select(result => {
                    if (!result.Item1.IsSuccess)
                    {
                        return RiakResult <RiakObject> .Error(result.Item1.ResultCode, result.Item1.ErrorMessage, result.Item1.NodeOffline);
                    }
                    if (result.Item1.Value.vclock == null)
                    {
                        return RiakResult <RiakObject> .Error(ResultCode.NotFound, "Unable to find value in Riak", false);
                    }

                    var o = new RiakObject(result.Item2.Bucket, result.Item2.Key, result.Item1.Value.content.First(), result.Item1.Value.vclock);
                    if (result.Item1.Value.content.Count > 1)
                    {
                        o.Siblings = result.Item1.Value.content.Select(
                            c => new RiakObject(result.Item2.Bucket, result.Item2.Key, c, result.Item1.Value.vclock)).ToList();
                    }

                    return RiakResult <RiakObject> .Success(o);
                });
            }));
        }
Пример #6
0
        public Task <RiakResult <RiakBucketProperties> > GetBucketProperties(string bucket, bool extended = false)
        {
            // bucket names cannot have slashes in the names, the REST interface doesn't like it at all
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult <RiakBucketProperties> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (extended)
            {
                var request = new RiakRestRequest(ToBucketUri(bucket), RiakConstants.Rest.HttpMethod.Get)
                              .AddQueryParam(RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesKey,
                                             RiakConstants.Rest.QueryParameters.Bucket.GetPropertiesValue);

                return(UseConnection(conn => conn.RestRequest(request))
                       .ContinueWith((Task <RiakResult <RiakRestResponse> > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess)
                    {
                        if (result.Value.StatusCode == HttpStatusCode.OK)
                        {
                            var response = new RiakBucketProperties(result.Value);
                            return RiakResult <RiakBucketProperties> .Success(response);
                        }
                        return RiakResult <RiakBucketProperties> .Error(ResultCode.InvalidResponse,
                                                                        "Unexpected Status Code: {0} ({1})".Fmt(result.Value.StatusCode, (int)result.Value.StatusCode), false);
                    }
                    return RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }));
            }
            else
            {
                var bpReq = new RpbGetBucketReq {
                    bucket = bucket.ToRiakString()
                };
                return(UseConnection(conn => conn.PbcWriteRead <RpbGetBucketReq, RpbGetBucketResp>(bpReq))
                       .ContinueWith((Task <RiakResult <RpbGetBucketResp> > finishedTask) => {
                    var result = finishedTask.Result;
                    if (result.IsSuccess)
                    {
                        var props = new RiakBucketProperties(result.Value.props);
                        return RiakResult <RiakBucketProperties> .Success(props);
                    }
                    return RiakResult <RiakBucketProperties> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }));
            }
        }
Пример #7
0
        public Task <RiakResult <IList <RiakObject> > > WalkLinks(RiakObject riakObject, IList <RiakLink> riakLinks)
        {
            System.Diagnostics.Debug.Assert(riakLinks.Count > 0, "Link walking requires at least one link");

            var input = new RiakBucketKeyInput();

            input.AddBucketKey(riakObject.Bucket, riakObject.Key);

            var query = new RiakMapReduceQuery()
                        .Inputs(input);

            var lastLink = riakLinks.Last();

            foreach (var riakLink in riakLinks)
            {
                var link = riakLink;
                var keep = ReferenceEquals(link, lastLink);
                query.Link(l => l.FromRiakLink(link).Keep(keep));
            }

            return(MapReduce(query)
                   .ContinueWith((Task <RiakResult <RiakMapReduceResult> > finishedTask) => {
                var result = finishedTask.Result;
                if (result.IsSuccess)
                {
                    var linkResults = result.Value.PhaseResults.GroupBy(r => r.Phase).Where(g => g.Key == riakLinks.Count - 1);
                    var linkResultStrings = linkResults.SelectMany(lr => lr.ToList(), (lr, r) => new { lr, r })
                                            .SelectMany(@t => @t.r.Values, (@t, s) => s.FromRiakString());

                    //var linkResultStrings = linkResults.SelectMany(g => g.Select(r => r.Values.Value.FromRiakString()));
                    var rawLinks = linkResultStrings.SelectMany(RiakLink.ParseArrayFromJsonString).Distinct();
                    var oids = rawLinks.Select(l => new RiakObjectId(l.Bucket, l.Key)).ToList();

                    return Get(oids, new RiakGetOptions())
                    .ContinueWith((Task <IEnumerable <RiakResult <RiakObject> > > getTask) => {
                        var objects = getTask.Result;

                        // FIXME
                        // we could be discarding results here. Not good?
                        // This really should be a multi-phase map/reduce
                        return RiakResult <IList <RiakObject> > .Success(objects.Where(r => r.IsSuccess).Select(r => r.Value).ToList());
                    });
                }
                return RiakResult <IList <RiakObject> > .ErrorTask(result.ResultCode, result.ErrorMessage, result.NodeOffline);
            }).Unwrap());
        }
Пример #8
0
 public Task <IEnumerable <RiakResult> > DeleteBucket(string bucket, RiakDeleteOptions deleteOptions)
 {
     return(UseConnection(conn => {
         return ListKeys(conn, bucket)
         .ContinueWith((Task <RiakResult <IEnumerable <string> > > finishedListingKeys) => {
             var keyResults = finishedListingKeys.Result;
             if (keyResults.IsSuccess)
             {
                 var objectIds = keyResults.Value.Select(key => new RiakObjectId(bucket, key)).ToList();
                 return Delete(conn, objectIds, deleteOptions);
             }
             return RiakResult <IEnumerable <RiakResult> > .ErrorTask(keyResults.ResultCode, keyResults.ErrorMessage, keyResults.NodeOffline);
         }).Unwrap();
     }).ContinueWith((Task <RiakResult <IEnumerable <RiakResult> > > finishedTask) => {
         return finishedTask.Result.Value;
     }));
 }
Пример #9
0
        public Task <IEnumerable <RiakResult <RiakObject> > > Put(IEnumerable <RiakObject> values, RiakPutOptions options = null)
        {
            options = options ?? new RiakPutOptions();

            return(UseConnection(conn => {
                return AfterAll(values.Select(v => {
                    if (!IsValidBucketOrKey(v.Bucket))
                    {
                        return RiakResult <RpbPutResp> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false);
                    }

                    if (!IsValidBucketOrKey(v.Key))
                    {
                        return RiakResult <RpbPutResp> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false);
                    }

                    var msg = v.ToMessage();
                    options.Populate(msg);

                    return conn.PbcWriteRead <RpbPutReq, RpbPutResp>(msg);
                })).ContinueWith((Task <IEnumerable <RiakResult <RpbPutResp> > > finishedTask) => {
                    return RiakResult <IEnumerable <RiakResult <RpbPutResp> > > .Success(finishedTask.Result);
                });
            }).ContinueWith((Task <RiakResult <IEnumerable <RiakResult <RpbPutResp> > > > finishedTask) => {
                var results = finishedTask.Result;
                return results.Value.Zip(values, Tuple.Create).Select(t => {
                    if (t.Item1.IsSuccess)
                    {
                        var finalResult = options.ReturnBody
                            ? new RiakObject(t.Item2.Bucket, t.Item2.Key, t.Item1.Value.content.First(), t.Item1.Value.vclock)
                                : t.Item2;

                        if (options.ReturnBody && t.Item1.Value.content.Count > 1)
                        {
                            finalResult.Siblings = t.Item1.Value.content.Select(
                                c => new RiakObject(t.Item2.Bucket, t.Item2.Key, c, t.Item1.Value.vclock)).ToList();
                        }

                        return RiakResult <RiakObject> .Success(finalResult);
                    }

                    return RiakResult <RiakObject> .Error(t.Item1.ResultCode, t.Item1.ErrorMessage, t.Item1.NodeOffline);
                });
            }));
        }
Пример #10
0
        public Task <RiakResult> Delete(string bucket, string key, RiakDeleteOptions options = null)
        {
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult.ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(key))
            {
                return(RiakResult.ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            var request = new RpbDelReq {
                bucket = bucket.ToRiakString(), key = key.ToRiakString()
            };

            options = options ?? new RiakDeleteOptions();
            options.Populate(request);
            return(UseConnection(conn => conn.PbcWriteRead(request, MessageCode.DelResp)));
        }
Пример #11
0
        public Task <RiakResult <RiakObject> > Put(RiakObject value, RiakPutOptions options = null)
        {
            if (!IsValidBucketOrKey(value.Bucket))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(value.Key))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            var request = value.ToMessage();

            options = options ?? new RiakPutOptions();
            options.Populate(request);

            return(UseConnection(conn => conn.PbcWriteRead <RpbPutReq, RpbPutResp>(request))
                   .ContinueWith((Task <RiakResult <RpbPutResp> > finishedTask) => {
                var result = finishedTask.Result;

                if (!result.IsSuccess)
                {
                    return RiakResult <RiakObject> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }

                var finalResult = options.ReturnBody
                        ? new RiakObject(value.Bucket, value.Key, result.Value.content.First(), result.Value.vclock)
                            : value;

                if (options.ReturnBody && result.Value.content.Count > 1)
                {
                    finalResult.Siblings = result.Value.content.Select(
                        c => new RiakObject(value.Bucket, value.Key, c, result.Value.vclock)).ToList();
                }

                return RiakResult <RiakObject> .Success(finalResult);
            }));
        }
Пример #12
0
        public Task <RiakResult <RiakObject> > Get(string bucket, string key, RiakGetOptions options = null)
        {
            if (!IsValidBucketOrKey(bucket))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidBucketErrorMessage, false));
            }

            if (!IsValidBucketOrKey(key))
            {
                return(RiakResult <RiakObject> .ErrorTask(ResultCode.InvalidRequest, InvalidKeyErrorMessage, false));
            }

            var request = new RpbGetReq {
                bucket = bucket.ToRiakString(), key = key.ToRiakString()
            };

            options = options ?? new RiakGetOptions();
            options.Populate(request);

            return(UseConnection(conn => conn.PbcWriteRead <RpbGetReq, RpbGetResp>(request))
                   .ContinueWith((Task <RiakResult <RpbGetResp> > finishedTask) => {
                var result = finishedTask.Result;
                if (!result.IsSuccess)
                {
                    return RiakResult <RiakObject> .Error(result.ResultCode, result.ErrorMessage, result.NodeOffline);
                }

                if (result.Value.vclock == null)
                {
                    return RiakResult <RiakObject> .Error(ResultCode.NotFound, "Unable to find value in Riak", false);
                }

                var o = new RiakObject(bucket, key, result.Value.content, result.Value.vclock);
                return RiakResult <RiakObject> .Success(o);
            }));
        }