Проблема с флагом клиента php memcached enyim

Я пытаюсь использовать memcached как с клиентом php (memcached), так и с клиентом C# (enyim). У меня есть сценарий, в котором я хочу получить значение CAS в php. Для этого я использую следующий код:

$memcached = new Memcached;
$memcached->addServer('localhost', 11211) or die ("Could not connect");
$memcached->setOption(Memcached::OPT_COMPRESSION, false); // the enyim client doesn't support compression
do {
    $entries = $memcached->get($theKey, null, $cas);
    if ($memcached->getResultCode() == Memcached::RES_NOTFOUND) {
        $entry = somearray("foo");
        $memcached->add($theKey, $entry);
    } else {
        $entries[] = "bar";
        $memcached->cas($cas, $theKey, $entries);
    }
}
while ($memcached->getResultCode() != Memcached::RES_SUCCESS AND $memcached->getResultCode() != Memcached::RES_END);

Все это работает хорошо и прекрасно с самого начала. Но затем, когда клиент C# C# имеет то же значение, все идет не так. Php выдает предупреждение по адресу:

$entries = $memcached->get($theKey, null, $cas);

а именно что:

 PHP Warning:  Memcached::get(): could not uncompress value in ... at line ...

И в результате возникает бесконечный цикл.

Сейчас попробовал получить ключ с memcached-сервера по телнету и данные тут же оказались. В php я также могу установить этот ключ без проблем.

Я заметил одну вещь: после того, как php-клиент что-то установил, флаг был равен 0. Теперь, после того как клиент C# получил значение CAS, флаг был 274. Происходит ли какое-то столкновение флагов в php-библиотеке? Или что-то еще?

Если кто-то может помочь мне решить эту проблему, я был бы благодарен!

лордстикс

[РЕДАКТИРОВАТЬ]

Ну тогда. Поскольку на этот вопрос нет ответа, позвольте мне выразиться по-другому. Есть ли способ помешать клиенту С# установить флаг 274?


person lordstyx    schedule 29.07.2011    source источник
comment
Я имею ту же самую проблему. Вы нашли решение?   -  person GRaecuS    schedule 07.09.2012
comment
Вау, это было почти год назад. Смотрите ответ, который я опубликовал, потому что он требует некоторого редактирования.   -  person lordstyx    schedule 07.09.2012
comment
@GRAecuS Забыл упомянуть ваше имя!   -  person lordstyx    schedule 08.09.2012


Ответы (3)


Так что в конце концов я нашел ответ на свою проблему. Это может не помочь всем вам, потому что я переключился с Enyim на клиент memcached BeIT (http://code.google.com/p/beitmemcached/)

Теперь, чтобы сделать клиент BeIT совместимым с клиентом php, вам нужно изменить Serializer.cs. В перечислении SerializedType я изменил число «String» на 0 и ByteArray на 2, что дало это:

internal enum SerializedType : ushort
{
    ByteArray   = 2,
    Object      = 1,
    String      = 0, //mod: turned around the numbers for String and ByteArray so it is compatible with php client
    Datetime    = 3,
    ....

Кажется, я выбрал BeIT, потому что не мог найти или понять, как работают флаги в клиенте Enyim. Если вы понимаете, как это работает, я уверен, что вы можете изменить этот клиент таким же образом.

person lordstyx    schedule 07.09.2012

Если я не ошибаюсь, смешивание языков/платформ с memcached — плохая идея. См. другой вопрос на аналогичную тему.

person Vijay Gill    schedule 29.07.2011
comment
Ну, я использую только один сервер memcached. Я сериализую переменные с помощью JSON, и, кроме того, если оба языка устанавливают значение один за другим для одного и того же ключа, я замечаю, что значение изменяется (при просмотре через telnet). Клиент C# также может прочитать все, что php установил в кеше. Возможно, флаг вызывает некоторые конфликты в php lib, но если это проблема, я могу найти обходной путь. - person lordstyx; 30.07.2011

Для записи. Так как библиотека с открытым исходным кодом, то ее можно модифицировать.

В классе Enyim.Caching.Memcached.DefaultTranscoder измените функцию

    public static uint TypeCodeToFlag(TypeCode code)
    {
        return (uint)((int)code | 0x0100);
    }

to

    public static uint TypeCodeToFlag(TypeCode code)
    {
        if (code == TypeCode.String)
        {
            return 0;
        }
        return (uint)((int)code | 0x0100);
    }

274 = TypeCode.String | 0x0100

Поскольку я не знаю протокола memcache, я не знаю, что происходит. Однако для memcache php требуется 0, поэтому я устанавливаю ноль, когда определенная переменная является строкой.

ps: beitmemcached давно не обновлялся.

person magallanes    schedule 19.09.2017