public void First_modification_date_is_returned_on_dequeue() {
     expirationResult = new Result<NotificationUpdateRecord>(TimeSpan.FromSeconds(10));
     var now = DateTime.UtcNow;
     var queue = new NotificationDelayQueue(TimeSpan.FromMilliseconds(500), ExpirationCallback);
     queue.Enqueue("foo", 1, 1, now, false);
     queue.Enqueue("foo", 1, 1, now.AddMinutes(1), false);
     queue.Enqueue("foo", 1, 1, now.AddMinutes(2), false);
     expirationResult.Wait();
     var pages = expirationResult.Value.Pages.ToList();
     Assert.AreEqual(1,pages.Count);
     Assert.AreEqual(now,pages[0].Item2);
 }
        private string CachedWebGet(XUri uri, double? ttl) {
            string id = uri.ToString();

            // fetch message from cache or from the web
            CacheEntry result;
            bool isNew = true;
            lock(_cacheLookup) {
                _cacheLookup.TryGetValue(id, out result);
            }

            // check if we have a cached entry
            if(result != null) {
                _log.DebugFormat("cache hit for '{0}'", result.Id);
                isNew = false;
                result.ResetMemoryExpiration();
                if(result.Cache != null) {
                    _log.DebugFormat("cache data in memory '{0}'", result.Id);
                    return result.Cache;
                }

                // we have the result on disk, so let's fetch it
                DreamMessage msg = Storage.At(CACHE_DATA, result.Guid + ".bin").GetAsync().Wait();
                if(msg.IsSuccessful) {
                    _log.DebugFormat("cache data pulled from disk");
                    result.Cache = Encoding.UTF8.GetString(msg.AsBytes());
                    return result.Cache;
                }
                _log.DebugFormat("unable to fetch cache data from disk: {0}", msg.Status);
            } else {
                _log.DebugFormat("new cache item for '{0}'", id);
                result = new CacheEntry(id, ttl);
            }

            // do the web request
            Result<DreamMessage> response = new Result<DreamMessage>();
            Plug.New(uri).WithTimeout(DEFAULT_WEB_TIMEOUT).InvokeEx("GET", DreamMessage.Ok(), response);
            DreamMessage message = response.Wait();
            try {

                // check message status
                if(!message.IsSuccessful) {
                    return message.Status == DreamStatus.UnableToConnect
                        ? string.Format("(unable to fetch text document from uri [status: {0} ({1}), message: \"{2}\"])", (int)message.Status, message.Status, message.ToDocument()["message"].AsText)
                        : string.Format("(unable to fetch text document from uri [status: {0} ({1})])", (int)message.Status, message.Status);
                }

                // check message size
                Result resMemorize = message.Memorize(_insertTextLimit, new Result()).Block();
                if(resMemorize.HasException) {
                    return "(text document is too large)";
                }

                // check if response is an XML document
                result.Cache = message.AsText() ?? string.Empty;
            } finally {
                message.Close();
            }

            // start timer to clean-up cached result
            if(result.Cache != null) {
                XDoc infoDoc = new XDoc("cache-entry")
                    .Elem("guid", result.Guid)
                    .Elem("id", result.Id)
                    .Elem("expires", result.Expires);
                lock(result) {
                    Storage.At(CACHE_DATA, result.Guid + ".bin").PutAsync(new DreamMessage(DreamStatus.Ok, null, MimeType.BINARY, Encoding.UTF8.GetBytes(result.Cache))).Wait();
                    Storage.At(CACHE_INFO, result.Guid + ".xml").PutAsync(infoDoc).Wait();
                }
                if(isNew) {
                    lock(_cacheLookup) {
                        _cacheLookup[id] = result;
                    }

                    // this timer removes the cache entry from disk 
                    SetupCacheTimer(result);
                }
            }
            return result.Cache;
        }
Example #3
0
        private StreamInfo GetFileInternal(string filename, MimeType type, bool allowFileLink) {

            if(allowFileLink && _allowRedirects) {
                return new StreamInfo(BuildS3Uri(Verb.GET, _s3.AtPath(filename), _redirectTimeout));
            }

            // check if file is cached
            var entry = GetCachedEntry(filename);
            if(entry != null) {
                Stream filestream = File.Open(entry.Item1, FileMode.Open, FileAccess.Read, FileShare.Read);
                return new StreamInfo(filestream, filestream.Length, type, entry.Item3);
            }

            // get file from S3
            var result = new Result<DreamMessage>();
            _s3.AtPath(filename).InvokeEx(Verb.GET, DreamMessage.Ok(), result);
            var response = result.Wait();
            try {
                if(response.IsSuccessful) {
                    return new StreamInfo(response.AsStream(), response.ContentLength, response.ContentType, GetLastModifiedTimestampFromResponse(response));
                }
                if(response.Status == DreamStatus.NotFound) {
                    response.Close();
                    return null;
                }
                throw new DreamInternalErrorException(string.Format("S3 unable to fetch file (status {0}, message {1})", response.Status, response.AsText()));
            } catch {
                if(response != null) {
                    response.Close();
                }
                throw;
            }
        }
        private static string CachedWebGet(XUri uri, double? ttl) {

            // fetch message from cache or from the web
            string result;
            lock(_webTextCache) {
                if(_webTextCache.TryGetValue(uri, out result)) {
                    return result;
                }
            }

            // do the web request
            Result<DreamMessage> response = new Result<DreamMessage>();
            Plug.New(uri).WithTimeout(DEFAULT_WEB_TIMEOUT).InvokeEx("GET", DreamMessage.Ok(), response);
            DreamMessage message = response.Wait();
            try {

                // check message status
                if(!message.IsSuccessful) {
                    return message.Status == DreamStatus.UnableToConnect
                        ? string.Format("(unable to fetch text document from uri [status: {0} ({1}), message: \"{2}\"])", (int)message.Status, message.Status, message.ToDocument()["message"].AsText)
                        : string.Format("(unable to fetch text document from uri [status: {0} ({1})])", (int)message.Status, message.Status);
                }

                // check message size
                Result resMemorize = message.Memorize(InsertTextLimit, new Result()).Block();
                if(resMemorize.HasException) {
                    return "(text document is too large)";
                }

                // check if response is an XML document
                result = message.AsText();
            } finally {
                message.Close();
            }

            // start timer to clean-up cached result
            if(result != null) {
                lock(_webTextCache) {
                    _webTextCache[uri] = result;
                }
                double timeout = Math.Min(60 * 60 * 24, Math.Max(ttl ?? MinCacheTtl, 60));
                TaskEnv.ExecuteNew(() => TaskTimer.New(TimeSpan.FromSeconds(timeout), delegate(TaskTimer timer) {
                    lock(_webTextCache) {
                        _webTextCache.Remove((XUri)timer.State);
                    }
                }, uri, TaskEnv.None));
            }
            return result;
        }
Example #5
0
 private void AssertFeature(string pattern, Result<DreamMessage> result, XDoc expected)
 {
     var feature = _blueprint[string.Format("features/feature[pattern='{0}']", pattern)];
     Assert.IsTrue(feature.Any(), string.Format("service doesn't have a feature for {0}", pattern));
     var doc = new XDoc("response").Elem("method", feature["method"].AsText);
     if(expected != null) {
         doc.Add(expected);
     }
     var response = result.Wait();
     Assert.IsTrue(response.IsSuccessful, response.GetErrorString());
     Assert.AreEqual(doc.ToCompactString(), response.ToDocument().ToCompactString());
 }
Example #6
0
File: Plug.cs Project: bjorg/DReAM
        public static DreamMessage WaitAndConfirm(Result<DreamMessage> result) {

            // NOTE (steveb): we don't need to set a time-out since 'Memorize()' already guarantees eventual termination

            result.Wait().Memorize(new Result(TimeSpan.MaxValue)).Wait();
            DreamMessage message = result.Value;
            if(!message.IsSuccessful) {
                throw new DreamResponseException(message);
            }
            return message;
        }
Example #7
0
        private static string CachedWebGet(XUri uri, double? ttl, bool? nilIfMissing) {

            // fetch message from cache or from the web
            string result;
            lock(_webTextCache) {
                if(_webTextCache.TryGetValue(uri, out result)) {
                    return result;
                }
            }

            // do the web request
            Result<DreamMessage> response = new Result<DreamMessage>();
            Plug.New(uri).WithTimeout(DEFAULT_WEB_TIMEOUT).InvokeEx("GET", DreamMessage.Ok(), response);
            DreamMessage message = response.Wait();
            try {

                // check message status
                if(!message.IsSuccessful) {
                    if(nilIfMissing.GetValueOrDefault()) {
                        return null;
                    }
                    return message.Status == DreamStatus.UnableToConnect
                        ? string.Format("(unable to fetch text document from uri [status: {0} ({1}), message: \"{2}\"])", (int)message.Status, message.Status, message.ToDocument()["message"].AsText)
                        : string.Format("(unable to fetch text document from uri [status: {0} ({1})])", (int)message.Status, message.Status);
                }

                // check message size
                Result resMemorize = message.Memorize(InsertTextLimit, new Result()).Block();
                if(resMemorize.HasException) {
                    return nilIfMissing.GetValueOrDefault() ? null : "(text document is too large)";
                }

                // detect encoding and decode response
                var stream = message.AsStream();
                var encoding = stream.DetectEncoding() ?? message.ContentType.CharSet;
                result = encoding.GetString(stream.ReadBytes(-1));
            } finally {
                message.Close();
            }

            // start timer to clean-up cached result
            lock(_webTextCache) {
                _webTextCache[uri] = result;
            }
            double timeout = Math.Min(60 * 60 * 24, Math.Max(ttl ?? MinCacheTtl, 60));
            TaskEnv.ExecuteNew(() => TaskTimer.New(TimeSpan.FromSeconds(timeout), timer => {
                lock(_webTextCache) {
                    _webTextCache.Remove((XUri)timer.State);
                }
            }, uri, TaskEnv.None));
            return result;
        }
		public void Should_Get_Results_Asychronously()
		{
			string obj = @"{""test"": ""prop""}";
			CouchDatabase db = client.GetDatabase(baseDatabase);
			db.CreateDocument("TEST", obj, new Result<string>()).Wait();

			string val1 = null;
			string val2 = null;

			Result<string> res1 = new Result<string>();
			Result<string> res2 = new Result<string>();
			db.GetDocument("TEST", res1);
			db.GetDocument("TEST", res2);

			res2.Wait();
			res1.Wait();

		}