19 #include "memcached_p.h"
21 #include <Cutelyst/Application>
22 #include <Cutelyst/Engine>
23 #include <Cutelyst/Context>
26 #include <QStringList>
27 #include <QLoggingCategory>
29 Q_LOGGING_CATEGORY(C_MEMCACHED,
"cutelyst.plugin.memcached", QtWarningMsg)
31 using namespace Cutelyst;
33 static thread_local
Memcached *mcd =
nullptr;
34 const time_t
Memcached::expirationNotAdd = MEMCACHED_EXPIRATION_NOT_ADD;
37 Plugin(parent), d_ptr(new MemcachedPrivate)
42 Memcached::~Memcached()
50 d->defaultConfig = defaultConfig;
57 const QVariantMap map = app->
engine()->
config(QStringLiteral(
"Cutelyst_Memcached_Plugin"));
60 const QStringList serverList = map.
value(QStringLiteral(
"servers"), d->defaultConfig.value(QStringLiteral(
"servers"))).toString().split(
QLatin1Char(
';'));
62 if (serverList.
empty()) {
63 config.
push_back(QStringLiteral(
"--SERVER=localhost"));
67 QStringLiteral(
"verify_key"),
68 QStringLiteral(
"remove_failed_servers"),
69 QStringLiteral(
"binary_protocol"),
70 QStringLiteral(
"buffer_requests"),
71 QStringLiteral(
"hash_with_namespace"),
72 QStringLiteral(
"noreply"),
73 QStringLiteral(
"randomize_replica_read"),
74 QStringLiteral(
"sort_hosts"),
75 QStringLiteral(
"support_cas"),
76 QStringLiteral(
"use_udp"),
77 QStringLiteral(
"tcp_nodelay"),
78 QStringLiteral(
"tcp_keepalive")
80 if (map.value(flag, d->defaultConfig.value(flag,
false)).toBool()) {
86 const bool useUDP = map.value(QStringLiteral(
"use_udp"), d->defaultConfig.value(QStringLiteral(
"use_udp"),
false)).toBool();
89 QStringLiteral(
"connect_timeout"),
90 QStringLiteral(
"distribution"),
91 QStringLiteral(
"hash"),
92 QStringLiteral(
"number_of_replicas"),
93 QStringLiteral(
"namespace"),
94 QStringLiteral(
"retry_timeout"),
95 QStringLiteral(
"server_failure_limit"),
96 QStringLiteral(
"snd_timeout"),
97 QStringLiteral(
"socket_recv_size"),
98 QStringLiteral(
"socket_send_size"),
99 QStringLiteral(
"poll_timeout"),
100 QStringLiteral(
"io_bytes_watermark"),
101 QStringLiteral(
"io_key_prefetch"),
102 QStringLiteral(
"io_msg_watermark"),
103 QStringLiteral(
"rcv_timeout")
105 const QString _val = map.value(opt, d->defaultConfig.value(opt)).toString();
116 qCInfo(C_MEMCACHED,
"Setting up connection to memcached servers using libmemcached %s with the following configuration string: \"%s\"", memcached_lib_version(), configString.
constData());
118 memcached_st *new_memc = memcached(configString.
constData(), configString.
size());
122 if (!serverList.
empty()) {
123 for (
const QString &server : serverList) {
128 bool isSocket =
false;
129 if (!serverParts.
empty()) {
135 if (serverParts.
size() > 1) {
144 if (!isSocket && (serverParts.
size() > 2)) {
153 memcached_return_t rc;
155 rc = memcached_server_add_unix_socket_with_weight(new_memc, name.
toUtf8().
constData(), weight);
156 if (Q_LIKELY(memcached_success(rc))) {
157 qCInfo(C_MEMCACHED,
"Added memcached server on socket %s with weight %u.", qPrintable(name), weight);
159 qCWarning(C_MEMCACHED,
"Failed to add memcached server on socket %s with weight %u: %s", qPrintable(name), weight, memcached_strerror(new_memc, rc));
163 rc = memcached_server_add_udp_with_weight(new_memc, name.
toUtf8().
constData(), port, weight);
165 rc = memcached_server_add_with_weight(new_memc, name.
toUtf8().
constData(), port, weight);
167 if (Q_LIKELY(memcached_success(rc))) {
168 qCInfo(C_MEMCACHED,
"Added memcached server on host %s:%u with weight %u.", qPrintable(name), port, weight);
170 qCWarning(C_MEMCACHED,
"Failed to add memcached server on host %s:%u with weight %u: %s", qPrintable(name), port, weight, memcached_strerror(new_memc, rc));
176 if (Q_UNLIKELY(memcached_server_count(new_memc) == 0)) {
177 qCWarning(C_MEMCACHED,
"Failed to add any memcached server. Adding default server on localhost port 11211.");
178 memcached_return_t rc = memcached_server_add(new_memc,
"localhost", 11211);
179 if (Q_UNLIKELY(!memcached_success(rc))) {
180 qCCritical(C_MEMCACHED,
"Failed to add default memcached server. Memcached plugin will not work without a configured server! %s", memcached_strerror(new_memc, rc));
181 memcached_free(new_memc);
187 d->compression = map.value(QStringLiteral(
"compression"), d->defaultConfig.value(QStringLiteral(
"compression"),
false)).toBool();
188 d->compressionLevel = map.value(QStringLiteral(
"compression_level"), d->defaultConfig.value(QStringLiteral(
"compression_level"), -1)).toInt();
189 d->compressionThreshold = map.value(QStringLiteral(
"compression_threshold"), d->defaultConfig.value(QStringLiteral(
"compression_threshold"), 100)).toInt();
190 if (d->compression) {
191 qCInfo(C_MEMCACHED,
"Compression: enabled (Compression level: %i, Compression threshold: %i bytes)", d->compressionLevel, d->compressionThreshold);
193 qCInfo(C_MEMCACHED,
"Compression: disabled");
196 const QString encKey = map.value(QStringLiteral(
"encryption_key")).toString();
199 const memcached_return_t rt = memcached_set_encoding_key(new_memc, encKeyBa.
constData(), encKeyBa.
size());
200 if (Q_LIKELY(memcached_success(rt))) {
201 qCInfo(C_MEMCACHED,
"Encryption: enabled");
203 qCWarning(C_MEMCACHED,
"Failed to enable encryption: %s", memcached_strerror(new_memc, rt));
206 qCInfo(C_MEMCACHED,
"Encryption: disabled");
209 #ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
210 #if LIBMEMCACHED_WITH_SASL_SUPPORT == 1
211 const QString saslUser = map.value(QStringLiteral(
"sasl_user")).toString();
212 const QString saslPass = map.value(QStringLiteral(
"sasl_password")).toString();
215 if (Q_LIKELY(memcached_success(rt))) {
216 qCInfo(C_MEMCACHED,
"SASL authentication: enabled");
217 d->saslEnabled =
true;
219 qCWarning(C_MEMCACHED,
"Failed to enable SASL authentication: %s", memcached_strerror(new_memc, rt));
222 qCInfo(C_MEMCACHED,
"SASL authentication: disabled");
228 memcached_free(d->memc);
240 qCCritical(C_MEMCACHED) <<
"Failed to configure the connection to the memcached server(s)";
249 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
258 MemcachedPrivate::Flags flags;
261 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
262 flags |= MemcachedPrivate::Compressed;
263 _value = qCompress(value, mcd->d_ptr->compressionLevel);
266 const memcached_return_t rt = memcached_set(mcd->d_ptr->memc,
274 const bool ok = memcached_success(rt);
277 qCWarning(C_MEMCACHED,
"Failed to store key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
280 MemcachedPrivate::setReturnType(returnType, rt);
288 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
298 MemcachedPrivate::Flags flags;
301 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
302 flags |= MemcachedPrivate::Compressed;
303 _value = qCompress(value, mcd->d_ptr->compressionLevel);
306 const memcached_return_t rt = memcached_set_by_key(mcd->d_ptr->memc,
316 const bool ok = memcached_success(rt);
319 qCWarning(C_MEMCACHED,
"Failed to store key \"%s\" on group \"%s\": %s", _key.
constData(), _groupKey.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
322 MemcachedPrivate::setReturnType(returnType, rt);
330 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
339 MemcachedPrivate::Flags flags;
342 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
343 flags |= MemcachedPrivate::Compressed;
344 _value = qCompress(value, mcd->d_ptr->compressionLevel);
347 const memcached_return_t rt = memcached_add(mcd->d_ptr->memc,
355 const bool ok = memcached_success(rt);
357 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
358 qCWarning(C_MEMCACHED,
"Failed to add key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
361 MemcachedPrivate::setReturnType(returnType, rt);
369 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
379 MemcachedPrivate::Flags flags;
382 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
383 flags |= MemcachedPrivate::Compressed;
384 _value = qCompress(value, mcd->d_ptr->compressionLevel);
387 const memcached_return_t rt = memcached_add_by_key(mcd->d_ptr->memc,
397 const bool ok = memcached_success(rt);
399 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
400 qCWarning(C_MEMCACHED,
"Failed to add key \"%s\" on group \"%s\": %s", _key.
constData(), _groupKey.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
403 MemcachedPrivate::setReturnType(returnType, rt);
411 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
420 MemcachedPrivate::Flags flags;
423 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
424 flags |= MemcachedPrivate::Compressed;
425 _value = qCompress(value, mcd->d_ptr->compressionLevel);
428 const memcached_return_t rt = memcached_replace(mcd->d_ptr->memc,
436 const bool ok = memcached_success(rt);
438 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
439 qCWarning(C_MEMCACHED,
"Failed to replace key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
442 MemcachedPrivate::setReturnType(returnType, rt);
450 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
460 MemcachedPrivate::Flags flags;
463 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
464 flags |= MemcachedPrivate::Compressed;
465 _value = qCompress(value, mcd->d_ptr->compressionLevel);
468 const memcached_return_t rt = memcached_replace_by_key(mcd->d_ptr->memc,
478 const bool ok = memcached_success(rt);
480 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
481 qCWarning(C_MEMCACHED,
"Failed to replace key \"%s\" on group \"%s\": %s", _key.
constData(), _groupKey.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
484 MemcachedPrivate::setReturnType(returnType, rt);
494 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
501 memcached_return_t rt;
505 std::vector<const char *> keys;
506 std::vector<size_t> sizes;
508 sizes.push_back(_key.
size());
509 rt = memcached_mget(mcd->d_ptr->memc,
514 if (memcached_success(rt)) {
515 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
517 retData =
QByteArray(memcached_result_value(result), memcached_result_length(result));
519 *cas = memcached_result_cas(result);
521 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
522 if (flags.testFlag(MemcachedPrivate::Compressed)) {
523 retData = qUncompress(retData);
528 memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
530 memcached_result_free(result);
533 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
534 qCWarning(C_MEMCACHED,
"Failed to get data for key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
537 MemcachedPrivate::setReturnType(returnType, rt);
547 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
554 memcached_return_t rt;
559 std::vector<const char *> keys;
560 std::vector<size_t> sizes;
562 sizes.push_back(_key.
size());
563 rt = memcached_mget_by_key(mcd->d_ptr->memc,
570 if (memcached_success(rt)) {
571 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
573 retData =
QByteArray(memcached_result_value(result), memcached_result_length(result));
575 *cas = memcached_result_cas(result);
577 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
578 if (flags.testFlag(MemcachedPrivate::Compressed)) {
579 retData = qUncompress(retData);
584 memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
586 memcached_result_free(result);
589 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
590 qCWarning(C_MEMCACHED,
"Failed to get data for key \"%s\" on group \"%s\": %s", _key.
constData(), _groupKey.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
593 MemcachedPrivate::setReturnType(returnType, rt);
601 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
610 const memcached_return_t rt = memcached_delete(mcd->d_ptr->memc,
615 const bool ok = memcached_success(rt);
617 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
618 qCWarning(C_MEMCACHED,
"Failed to remove data for key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
621 MemcachedPrivate::setReturnType(returnType, rt);
629 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
639 const memcached_return_t rt = memcached_delete_by_key(mcd->d_ptr->memc,
646 const bool ok = memcached_success(rt);
648 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
649 qCWarning(C_MEMCACHED,
"Failed to remove data for key \"%s\" on group \"%s\": %s", _key.
constData(), _groupKey.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
652 MemcachedPrivate::setReturnType(returnType, rt);
660 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
669 const memcached_return_t rt = memcached_exist(mcd->d_ptr->memc,
673 const bool ok = memcached_success(rt);
675 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
676 qCWarning(C_MEMCACHED,
"Failed to check existence of key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
679 MemcachedPrivate::setReturnType(returnType, rt);
687 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
697 const memcached_return_t rt = memcached_exist_by_key(mcd->d_ptr->memc,
703 const bool ok = memcached_success(rt);
705 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
706 qCWarning(C_MEMCACHED,
"Failed to check existence of key \"%s\" in group \"%s\"", _key.
constData(), _groupKey.
constData());
709 MemcachedPrivate::setReturnType(returnType, rt);
717 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
726 const memcached_return_t rt = memcached_increment(mcd->d_ptr->memc,
732 const bool ok = memcached_success(rt);
734 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
735 qCWarning(C_MEMCACHED,
"Failed to increment key \"%s\" by %u: %s", _key.
constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
738 MemcachedPrivate::setReturnType(returnType, rt);
746 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
756 const memcached_return_t rt = memcached_increment_by_key(mcd->d_ptr->memc,
764 const bool ok = memcached_success(rt);
766 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
767 qCWarning(C_MEMCACHED,
"Failed to increment \"%s\" key on group \"%s\" by %lu: %s", _key.
constData(), _group.
constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
770 MemcachedPrivate::setReturnType(returnType, rt);
778 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
787 const memcached_return_t rt = memcached_increment_with_initial(mcd->d_ptr->memc,
795 const bool ok = memcached_success(rt);
798 qCWarning(C_MEMCACHED,
"Failed to increment or initialize key \"%s\" by offset %lu or initial %lu: %s", _key.
constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
801 MemcachedPrivate::setReturnType(returnType, rt);
809 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
819 const memcached_return_t rt = memcached_increment_with_initial_by_key(mcd->d_ptr->memc,
829 const bool ok = memcached_success(rt);
831 qCWarning(C_MEMCACHED,
"Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or initial %lu: %s", _key.
constData(), _group.
constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
834 MemcachedPrivate::setReturnType(returnType, rt);
842 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
851 const memcached_return_t rt = memcached_decrement(mcd->d_ptr->memc,
857 const bool ok = memcached_success(rt);
859 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
860 qCWarning(C_MEMCACHED,
"Failed to decrement key \"%s\" by %u: %s", _key.
constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
863 MemcachedPrivate::setReturnType(returnType, rt);
871 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
881 const memcached_return_t rt = memcached_decrement_by_key(mcd->d_ptr->memc,
889 const bool ok = memcached_success(rt);
891 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
892 qCWarning(C_MEMCACHED,
"Failed to decrement \"%s\" key on group \"%s\" by %lu: %s", _key.
constData(), _group.
constData(), offset, memcached_strerror(mcd->d_ptr->memc, rt));
895 MemcachedPrivate::setReturnType(returnType, rt);
903 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
912 const memcached_return_t rt = memcached_decrement_with_initial(mcd->d_ptr->memc,
920 const bool ok = memcached_success(rt);
923 qCWarning(C_MEMCACHED,
"Failed to decrement or initialize key \"%s\" by offset %lu or initial %lu: %s", _key.
constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
926 MemcachedPrivate::setReturnType(returnType, rt);
934 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
944 const memcached_return_t rt = memcached_decrement_with_initial_by_key(mcd->d_ptr->memc,
954 const bool ok = memcached_success(rt);
956 qCWarning(C_MEMCACHED,
"Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or initial %lu: %s", _key.
constData(), _group.
constData(), offset, initial, memcached_strerror(mcd->d_ptr->memc, rt));
959 MemcachedPrivate::setReturnType(returnType, rt);
967 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
976 MemcachedPrivate::Flags flags;
979 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
980 flags |= MemcachedPrivate::Compressed;
981 _value = qCompress(value, mcd->d_ptr->compressionLevel);
984 const memcached_return_t rt = memcached_cas(mcd->d_ptr->memc,
993 const bool ok = memcached_success(rt);
995 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
996 qCWarning(C_MEMCACHED,
"Failed to compare and set (cas) key \"%s\": %s", _key.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
999 MemcachedPrivate::setReturnType(returnType, rt);
1007 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1017 MemcachedPrivate::Flags flags;
1020 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
1021 flags |= MemcachedPrivate::Compressed;
1022 _value = qCompress(value, mcd->d_ptr->compressionLevel);
1025 const memcached_return_t rt = memcached_cas_by_key(mcd->d_ptr->memc,
1036 const bool ok = memcached_success(rt);
1038 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1039 qCWarning(C_MEMCACHED,
"Failed to compare and set (cas) key \"%s\" in group \"%s\": %s", _key.
constData(), _group.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
1042 MemcachedPrivate::setReturnType(returnType, rt);
1050 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1057 const memcached_return_t rt = memcached_flush_buffers(mcd->d_ptr->memc);
1059 const bool ok = memcached_success(rt);
1062 qCWarning(C_MEMCACHED,
"Failed to flush buffers: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1065 MemcachedPrivate::setReturnType(returnType, rt);
1073 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1080 const memcached_return_t rt = memcached_flush(mcd->d_ptr->memc, expiration);
1082 const bool ok = memcached_success(rt);
1085 qCWarning(C_MEMCACHED,
"Failed to wipe clean (flush) server content: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1088 MemcachedPrivate::setReturnType(returnType, rt);
1098 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1106 qCWarning(C_MEMCACHED,
"Can not get multiple values without a list of keys.");
1113 std::vector<char *> _keys;
1115 std::vector<size_t> _keysSizes;
1116 _keysSizes.reserve(keys.
size());
1118 for (
const QString &key : keys) {
1120 char *data =
new char[_key.
size() + 1];
1121 strcpy(data, _key.
data());
1123 _keysSizes.push_back(_key.
size());
1126 memcached_return_t rt;
1129 rt = memcached_mget(mcd->d_ptr->memc,
1134 if (memcached_success(rt)) {
1137 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1138 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1141 QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1143 casValues->
insert(rk, memcached_result_cas(result));
1145 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
1146 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1147 rd = qUncompress(rd);
1151 memcached_result_free(result);
1155 for (
char *c : _keys) {
1160 qCWarning(C_MEMCACHED,
"Failed to get values for multiple keys: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1163 MemcachedPrivate::setReturnType(returnType, rt);
1173 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1181 qCWarning(C_MEMCACHED,
"Can not get multiple values from specific server when groupKey is empty.");
1189 qCWarning(C_MEMCACHED,
"Can not get multiple values without a list of keys.");
1198 std::vector<char *> _keys;
1200 std::vector<size_t> _keysSizes;
1201 _keysSizes.reserve(keys.
size());
1203 for (
const QString &key : keys) {
1205 char *data =
new char[_key.
size() + 1];
1206 strcpy(data, _key.
data());
1208 _keysSizes.push_back(_key.
size());
1211 memcached_return_t rt;
1214 rt = memcached_mget_by_key(mcd->d_ptr->memc,
1223 if (memcached_success(rt)) {
1226 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1227 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1230 QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1232 casValues->
insert(rk, memcached_result_cas(result));
1234 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
1235 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1236 rd = qUncompress(rd);
1240 memcached_result_free(result);
1244 for (
char *c : _keys) {
1249 qCWarning(C_MEMCACHED,
"Failed to get values for multiple keys in group \"%s\": %s", _group.
constData(), memcached_strerror(mcd->d_ptr->memc, rt));
1252 MemcachedPrivate::setReturnType(returnType, rt);
1260 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1269 const memcached_return_t rt = memcached_touch(mcd->d_ptr->memc,
1274 const bool ok = memcached_success(rt);
1277 qCWarning(C_MEMCACHED,
"Failed to touch key \"%s\" with new expiration time %lu: %s", _key.
constData(), expiration, memcached_strerror(mcd->d_ptr->memc, rt));
1280 MemcachedPrivate::setReturnType(returnType, rt);
1288 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1298 const memcached_return_t rt = memcached_touch_by_key(mcd->d_ptr->memc,
1305 const bool ok = memcached_success(rt);
1308 qCWarning(C_MEMCACHED,
"Failed to touch key \"%s\" in group \"%s\" with new expiration time %lu: %s", _key.
constData(), _group.
constData(), expiration, memcached_strerror(mcd->d_ptr->memc, rt));
1311 MemcachedPrivate::setReturnType(returnType, rt);
1320 return c->
translate(
"Cutelyst::Memcached",
"The request was successfully executed.");
1322 return c->
translate(
"Cutelyst::Memcached",
"An unknown failure has occurred in the Memcached server.");
1324 return c->
translate(
"Cutelyst::Memcached",
"A DNS failure has occurred.");
1326 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occured while trying to connect to a Memcached server.");
1328 return c->
translate(
"Cutelyst::Memcached",
"An error has occured while trying to write to a Memcached server.");
1330 return c->
translate(
"Cutelyst::Memcached",
"An error has occured while trying to read from a Memcached server.");
1332 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occured while trying to read from a Memcached server. This only occures when either there is a bug in the server, or in rare cases where an ethernet NIC is reporting dubious information.");
1334 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occured in the Memcached protocol.");
1336 return c->
translate(
"Cutelyst::Memcached",
"An unknown Memcached client error has occured internally.");
1338 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occured in the Memcached server.");
1340 return c->
translate(
"Cutelyst::Memcached",
"A general error occured.");
1342 return c->
translate(
"Cutelyst::Memcached",
"The data for the given key alrey exists.");
1344 return c->
translate(
"Cutelyst::Memcached",
"The data requested with the key given was not found.");
1346 return c->
translate(
"Cutelyst::Memcached",
"The request to store an object failed.");
1348 return c->
translate(
"Cutelyst::Memcached",
"The requested object has been successfully stored on the server.");
1350 return c->
translate(
"Cutelyst::Memcached",
"The object requested was not found.");
1352 return c->
translate(
"Cutelyst::Memcached",
"An error has occurred while trying to allocate memory.");
1354 return c->
translate(
"Cutelyst::Memcached",
"The read operation was only partcially successful.");
1356 return c->
translate(
"Cutelyst::Memcached",
"A multi request has been made, and some underterminate number of errors have occurred.");
1358 return c->
translate(
"Cutelyst::Memcached",
"No servers have been added to the Memcached plugin.");
1360 return c->
translate(
"Cutelyst::Memcached",
"The Memcached server has completed returning all of the objects requested.");
1362 return c->
translate(
"Cutelyst::Memcached",
"The object requested by the key has been deleted.");
1364 return c->
translate(
"Cutelyst::Memcached",
"A “stat” command has been returned in the protocol.");
1366 return c->
translate(
"Cutelyst::Memcached",
"An error has occurred in the driver which has set errno.");
1368 return c->
translate(
"Cutelyst::Memcached",
"The given method is not supported in the Memcached server.");
1370 return c->
translate(
"Cutelyst::Memcached",
"A request has been made, but the Memcached server has not finished the fetch of the last request.");
1372 return c->
translate(
"Cutelyst::Memcached",
"The operation has timed out.");
1374 return c->
translate(
"Cutelyst::Memcached",
"The request has been buffered.");
1376 return c->
translate(
"Cutelyst::Memcached",
"The key provided is not a valid key.");
1378 return c->
translate(
"Cutelyst::Memcached",
"The Memcached server you are connecting to has an invalid protocol. Most likely you are connecting to an older server that does not speak the binary protocol.");
1380 return c->
translate(
"Cutelyst::Memcached",
"The requested Memcached server has been marked dead.");
1382 return c->
translate(
"Cutelyst::Memcached",
"The Memcached server you are communicating with has a stat key which has not be defined in the protocol.");
1384 return c->
translate(
"Cutelyst::Memcached",
"Item is too large for the Memcached server to store.");
1386 return c->
translate(
"Cutelyst::Memcached",
"The arguments supplied to the given function were not valid.");
1388 return c->
translate(
"Cutelyst::Memcached",
"The key that has been provided is too large for the given Memcached server.");
1390 return c->
translate(
"Cutelyst::Memcached",
"An unknown issue has occured during SASL authentication.");
1392 return c->
translate(
"Cutelyst::Memcached",
"The credentials provided are not valid for this Memcached server.");
1394 return c->
translate(
"Cutelyst::Memcached",
"Authentication has been paused.");
1396 return c->
translate(
"Cutelyst::Memcached",
"An error has occurred while trying to parse the configuration string.");
1398 return c->
translate(
"Cutelyst::Memcached",
"An error has occurred in parsing the configuration string.");
1400 return c->
translate(
"Cutelyst::Memcached",
"The method that was requested has been deprecated.");
1402 return c->
translate(
"Cutelyst::Memcached",
"The Cutelyst Memcached plugin has not been registered to the application.");
1404 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occured.");
1458 case MEMCACHED_IN_PROGRESS:
return Memcached::InProgress;
1459 case MEMCACHED_SERVER_TEMPORARILY_DISABLED:
return Memcached::ServerTemporaryDisabled;
1460 case MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE:
return Memcached::ServerMemoryAllocationFailure;
1461 case MEMCACHED_MAXIMUM_RETURN:
return Memcached::MaximumReturn;
1469 *rt1 = MemcachedPrivate::returnTypeConvert(rt2);
1473 #include "moc_memcached.cpp"
static bool incrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool incrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool addByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool decrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
QVersionNumber fromString(const QString &string, int *suffixIndex)
static bool replace(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
iterator insert(const Key &key, const T &value)
static bool flush(time_t expiration, MemcachedReturnType *returnType=nullptr)
void postForked(Cutelyst::Application *app)
void push_back(const T &value)
static bool replaceByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool increment(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool casByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
static QString errorString(Context *c, MemcachedReturnType rt)
const T & at(int i) const
static bool touch(const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool flushBuffers(MemcachedReturnType *returnType=nullptr)
void loadTranslations(const QString &filename, const QString &directory=QString(), const QString &prefix=QString(), const QString &suffix=QString())
QString join(const QString &separator) const
static bool decrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static QHash< QString, QByteArray > mgetByKey(const QString &groupKey, const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
static QByteArray get(const QString &key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
static bool existByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType=nullptr)
static bool exist(const QString &key, MemcachedReturnType *returnType=nullptr)
static QHash< QString, QByteArray > mget(const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
void setDefaultConfig(const QVariantMap &defaultConfig)
QString fromUtf8(const char *str, int size)
const char * constData() const
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const
static bool setByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool touchByKey(const QString &groupKey, const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool decrement(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool removeByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType=nullptr)
static bool remove(const QString &key, MemcachedReturnType *returnType=nullptr)
virtual bool setup(Application *app) override
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
static QVersionNumber libMemcachedVersion()
Returns the version of the currently used libmemcached.
static bool cas(const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
The Cutelyst Application.
static QByteArray getByKey(const QString &groupKey, const QString &key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
Cutelyst Memcached plugin.
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
static bool incrementWithInitialByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool add(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
QVariantMap config(const QString &entity) const
user configuration for the application
static bool decrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
uint toUInt(bool *ok, int base) const
static bool set(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
QByteArray toUtf8() const