Node.jsでmemcachedのcasを使おうとしたら嵌ったので独自目線で纏めた

# はじめに
どうも、またしても私です。
今度はNode.jsでmemcachedを扱おうとして、casで嵌った話を共有したく思います。
まじでみんな気をつけて。

## 参考
https://www.npmjs.com/package/memcached

## 注意点
筆者はmemcached初心者です。
どれくらい初心者かと言うと、これを書いているのがmemcached触って3日目くらいです。
間違っている情報等あれば容赦なくコメントで指摘してください。

# memcachedとは
Wikiでも見てください。多分ぐぐるほうが私の説明より分かり易い。
KVSの単純なストレージなんだなーぐらいの認識です。
Redisよりも単純です。

業界的にはWebページを早く表示するためDBに直接アクセスするのではなく、
memcachedなどをキャッシュとして利用することも多いです。
ソーシャルゲーム等でも多いですよね。

# casとは
memcachedのメソッドの一つ。
Check-And-SetまたはCompare-And-Swapの略で、既存のキーの内容を更新することが出来る。
Setと異なりGetsで入手できるCASidとキーで更新するため、キーが存在しない場合やGetsからCASまでの間に更新された場合は上書きをしない。

## 実際に使ってみた

### 公式どおりにやった結果

```javascript:Set.js
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');

console.log(`hello, memcached.`);

memcached.set('foo', 'bar', 300, function (err, data) {
        if (err)
        {
                console.log(err);
        }
        else
        {
                console.log(`set success!`);
        }
});
```

```javascript:CAS.js
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');

console.log(`hello, memcached.`);

let casId;

memcached.gets('foo', function (err, data) {
        if (err)
        {
                console.log(err);
        }
        else
        {
                console.log(`gets success!`);
                if (data !== undefined)
                {
                        casId = data.cas;
                        console.log(data.foo);
                        console.log(data.cas);
                }
                else
                {
                        console.log(`foo is undefined.`);
                }
        }
});

const casFoo = function() {
        memcached.cas('foo', 'moke', casId, 300, function (err) {
                console.log(err);
                console.log(`cas success!`);
        });
}

setTimeout(casFoo, 10000);
```

```:Result
$ node CAS.js 
hello, memcached.
gets success!
bar
56
undefined
cas success!
```

errがundefinedになっている。なぜ？

### 正しい書き方

```javascript:Set_Answer.js
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');

console.log(`hello, memcached.`);

memcached.set('foo', 'bar', 300, function (err, data) {
        if (err)
        {
                console.log(err);
        }
        else
        {
                console.log(`set success!`);
        }
});
```

```javascript:CAS_Answer.js
const Memcached = require('memcached');
const memcached = new Memcached('localhost:11211');

console.log(`hello, memcached.`);

let casId;

memcached.gets('foo', function (err, data) {
        if (err)
        {
                console.log(err);
        }
        else
        {
                console.log(`gets success!`);
                if (data !== undefined)
                {
                        casId = data.cas;
                        console.log(data.foo);
                        console.log(data.cas);
                }
                else
                {
                        console.log(`foo is undefined.`);
                }
        }
});

const casFoo = function() {
        memcached.cas('foo', 'moke', casId, 300, function (err, result) {
                if (err) console.log(err);
                if (!result)
                {
                        console.log(result);
                } else {
                        console.log(`cas success!`);
                }
        });
}
```

```:Result_Answer
$ node CAS_Answer.js 
hello, memcached.
gets success!
bar
73
false
```

resultのなかにtrue/falseが記録されています。
そこでCASの結果を確認できます。

# おわりに
これを書く切欠となった上司に多大なる感謝を。
あとは何かあればコメントでどうぞ。