memcachedprotocol-bufferslibmemcachelibmemcached

memcache append/prepend with google protocol buffers


SOLVED: I tried appending a single SerialKey to the list. When I now append a SerialKeyList with one key, it works as it should be.

I am using memcached with libmemcached and the google protocol buffers to save a list in the cache which consists of a list of elements and a list of blacklisted elements.

The .proto is:

message SerialKeyList {
repeated SerialBlackKey bkey = 2;
repeated SerialKey key = 1;
}

message SerialKey {
optional string key = 1;
}

message SerialBlackKey {
optional string key = 2;
}

I would like to append single elements of either type SerialKey or SerialBlackKey with memcached_append(). I initialize the list with one SerialKey element (with memcached_set(SerialKeyList)), and then append one SerialBlackKey element (with memcached_append).

The result I am getting when parsing the list from memcached and printing with PrintDebugString() is

key {
  key: "REPL:http://a.host.com/replica" 
}
bkey {
  10: "PL:http://a.host.com/replica" 
}

So the two lists are created, but the 2nd element is not read correctly.

Should that be possible? From the Protobuf encoding documentation I understand that repeated fields do not have to follow another, so interleaving fields of the other type should be possible.

/EDIT: I have the same problem with only one type of element (SerialKey) in the list. Here I use a further attribute on SerialKey to decide whether it is in the blacklist. Proto:

message SerialKeyList {
  repeated SerialKey key = 1;
}

message SerialKey {
  required string key = 1;
  required bool white = 2 [default = true];
}

Solution

  • You are right - te spec states that implementations must allow fields in any order, specifically to support this append scenario.

    The key to appending is that it must still look like a SerialKeyList, even if you append a SerialKeyList with just a single SerialKey or SerialBlackKey.

    Note also: I have no idea if append works if you are using the string version - the binary version is certainly appendable, though.

    For a more specific answer you probably need to show how you are constructing this, and state which implementation you are using.