Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Async set-like commands interface #21

Closed
filonenko-mikhail opened this issue Dec 11, 2015 · 2 comments
Closed

Async set-like commands interface #21

filonenko-mikhail opened this issue Dec 11, 2015 · 2 comments

Comments

@filonenko-mikhail
Copy link

There is one async c memcached client library, thanks for it.
Internally all command use omcache_io. But there is no async interface for set commands.
Do you plan to add such functions?

@saaros
Copy link
Member

saaros commented Dec 21, 2015

I'm not sure what would be a good, generic C interface for asynchronous operations so async mechanisms are currently left to the users to implement. It's possible to do it using omcache_command and omcache_io similar to how the Python client does it.

Also, in case you're not interested in command statuses and just want to push updates to the servers (and potentially wait for operations to complete or fail without distinguishing between the results) it's possible to just use the plain command api (omcache_set and friends) with a zero timeout and later on call omcache_io to make sure all commands were sent. This is what https://github.com/ohmu/pgmemcache/ does by default.

@filonenko-mikhail
Copy link
Author

Ok, I will do.

For google indexing for people, who searches async memcached c++ interface.

struct protocol_binary_set_request_body_s {
  uint32_t flags;
  uint32_t expiration;
} __attribute__((packed));

static int async_omc_set_cmd(omcache_t *mc, protocol_binary_command opcode,
                             const unsigned char *key, size_t key_len,
                             const unsigned char *value, size_t value_len,

                             protocol_binary_set_request_body_s* expiration_and_flags,

                             uint64_t cas,

                             omcache_req_t *requests,
                             size_t *req_count,
                             omcache_value_t *values,
                             size_t *value_count,

                             int32_t timeout_msec)
{
  if (req_count == NULL || *req_count == 0)
    return OMCACHE_INVALID;

  memset(requests, 0, sizeof(*requests) * *req_count);
  if (values && value_count)
    memset(values, 0, sizeof(*values) * *value_count);


  size_t extra_len = sizeof(protocol_binary_set_request_body_s);
  if (opcode == PROTOCOL_BINARY_CMD_APPEND || opcode == PROTOCOL_BINARY_CMD_APPENDQ ||
      opcode == PROTOCOL_BINARY_CMD_PREPEND || opcode == PROTOCOL_BINARY_CMD_PREPENDQ)
    extra_len = 0;

  omcache_req_t& req = requests[0];
  req.server_index = -1;
  req.header.opcode = opcode;
  req.header.extlen = extra_len;
  req.header.keylen = htobe16(key_len);
  req.header.bodylen = htobe32(key_len + value_len + extra_len);
  req.header.cas = htobe64(cas);
  req.extra = expiration_and_flags;
  req.key = key;
  req.data = value;

  return omcache_command(mc, requests, req_count, values, value_count, timeout_msec);
}


int async_omcache_add(omcache_t *mc,
                      const unsigned char *key, size_t key_len,
                      const unsigned char *value, size_t value_len,

                      protocol_binary_set_request_body_s* expiration_and_flags,

                      omcache_req_t *requests,
                      size_t *req_count,
                      omcache_value_t *values,
                      size_t *value_count,

                      int32_t timeout_msec)
{
  return async_omc_set_cmd(mc, QCMD(PROTOCOL_BINARY_CMD_ADD),
                           key, key_len, value, value_len,
                           expiration_and_flags, 0,

                           requests,
                           req_count,
                           values,
                           value_count,

                           timeout_msec);
}

int async_omcache_delete(omcache_t *mc,
                         const unsigned char *key, size_t key_len,

                         omcache_req_t *requests,
                         size_t *req_count,
                         omcache_value_t *values,
                         size_t *value_count,
                         int32_t timeout_msec)
{
  if (req_count == NULL || *req_count == 0)
    return OMCACHE_INVALID;

  memset(requests, 0, sizeof(*requests) * *req_count);
  if (values && value_count)
    memset(values, 0, sizeof(*values) * *value_count);

  omcache_req_t *req = &requests[0];
  req->server_index = -1;
  req->header.opcode = QCMD(PROTOCOL_BINARY_CMD_DELETE);
  req->header.keylen = htobe16(key_len);
  req->header.bodylen = htobe32(key_len);
  req->key = key;
  return omcache_command(mc, requests, req_count, values, value_count, timeout_msec);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants