2

I build an out-of-process cache for my webpage's database. Though when I try to do something with it (Set, Get), I get the following error:

A task was canceled

Here's my redis cache code. any help would be great. thanks

public class RedisCache : ICache
{
    private RedisConnection redis;

public RedisCache()
{
    redis = new RedisConnection("127.0.0.1");
    redis.Open();
}

public object Get(string key)
{
    var method = redis.Strings.Get(0, key);
    if (method == null)
        return null;
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream(method.Result);
    object obj = bf.Deserialize(ms);
    return obj;
}

public void Set(string key, object value)
{
    MemoryStream ms = new MemoryStream();
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms, value);
    redis.Strings.Set(0, key, ms.ToArray());
}

}

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
DanielY
  • 1,141
  • 30
  • 58
  • 1
    What exact version are you using? If we assume it opened correctly, that should be fine. I'm not at a PC but I can add an example later – Marc Gravell May 17 '13 at 15:04
  • I'd love that. thanks. how do I check the version? – DanielY May 17 '13 at 15:11
  • 1
    any of: reference properties, file properties (right click on booksleeve.DLL in explorer), or the nuget package manager will tell you – Marc Gravell May 17 '13 at 15:16
  • Thanks. Booksleeve 1.3.37 – DanielY May 17 '13 at 15:18
  • 1
    k; can you change the "open" line to: `redis.Wait(redis.Open());` ? I'm wondering if it is failing to open... – Marc Gravell May 17 '13 at 15:20
  • By the way: unrelated to BookSleeve - I strongly suggest against using BinaryFormatter for serializing out-of-process. That could bite you later - it is notoriously brittle when versioning / refactoring your app. There are plenty of friendlier serializers that don't have this problem – Marc Gravell May 17 '13 at 15:22
  • Thanks for the tips @MarcGravell. After trying the redis.wait line you suggested I get "No connection could be made because the target machine actively refused it" error – DanielY May 17 '13 at 15:37
  • @MarcGravell maybe it's the wrong IP? I run it in the cloud so how would I know its ip and where to connect the client? – DanielY May 17 '13 at 15:44
  • 1
    could be firewall; is redis running on the same cloud machine? Or another? – Marc Gravell May 17 '13 at 16:31
  • I didn't understand the question. sorry @MarcGravell I wasn't around PC in the last 24 hours. I'll read your answer once I will, and comment – DanielY May 18 '13 at 17:38
  • 1
    all I mean is: you presumably have a redis server running somewhere. Where is that somewhere? Is it on the same machine? If not - do you know its name? IP? (I don't need to know what the name / IP is ... I'm just asking what you know about the server) – Marc Gravell May 18 '13 at 17:42
  • @MarcGravell I run my program (with the redis client) in my Azure cloud. How would I get a redis server runnning in it, too? Sorry i'm pretty new at this, trying to learn – DanielY May 18 '13 at 20:46
  • 1
    Again: ***where is your redis server???*** I assume you *have* a server somewhere running redis? You should have some kind of identity. How / where are you running redis? If you can describe your setup, I have an azure account - so I can try to repro it on my own cloud. – Marc Gravell May 18 '13 at 21:55
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/30198/discussion-between-user1067083-and-marc-gravell) – DanielY May 19 '13 at 05:34

1 Answers1

2

The "cancelled" status means that a message was queued but could not be written to the stream (for example, the stream never opened). From 1.3 onward, there are 2 main scenarios for this:

  • the message was queued because the connection was not open, and it was later discovered that the connection was impossible
  • a transaction was not issued because a pre-condition failed, or was aborted because "watch" key was changed

Since you aren't using transactions, it sounds like the connection couldn't be opened in the first place. You can check this by looking at the Task you get back from Open() - at the simplest:

redis.Wait(redis.Open());

The Wait method here is like the usual task.Wait(), but it has inbuilt timeout support, and a few other things to make life handy - I do encourage it's usage (mainly for convenience); likewise, redis.Wait(method) would be preferable to method.Result - but either will usually work fine. You could also await or ContinueWith the task - the key point here is that you need to check that it opened - and the only way to do that is by seeing what happens with the Task.

Note that the connection has some events for detecting failure (errors and closure). You may also find it conveneint to open the connection with ConnectionUtils, which has some inbuilt handling for a range of common scenarios.

On final observation: BinaryFormatter ... you may find when you version / refactor your API you can't load your old data - don't say I didn't warn you ;p I would recommend any contract based serializer instead: XmlSerializer, DataContractSerializer, JSON.NET, or protobuf-net (the latter being dense binary - ideal for opaque out-of-process BLOB such as redis, although I hear the author is nothing but trouble).

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900