6#include "memcached_p.h"
8#include <Cutelyst/Application>
9#include <Cutelyst/Context>
10#include <Cutelyst/Engine>
13#include <QLoggingCategory>
16Q_LOGGING_CATEGORY(C_MEMCACHED,
"cutelyst.plugin.memcached", QtWarningMsg)
20static thread_local Memcached *mcd =
nullptr;
25 , d_ptr(new MemcachedPrivate)
36 d->defaultConfig = defaultConfig;
43 const QVariantMap map = app->
engine()->
config(QStringLiteral(
"Cutelyst_Memcached_Plugin"));
47 map.value(QStringLiteral(
"servers"), d->defaultConfig.value(QStringLiteral(
"servers")))
51 if (serverList.
empty()) {
52 config.
push_back(QStringLiteral(
"--SERVER=localhost"));
56 QStringLiteral(
"verify_key"),
57 QStringLiteral(
"remove_failed_servers"),
58 QStringLiteral(
"binary_protocol"),
59 QStringLiteral(
"buffer_requests"),
60 QStringLiteral(
"hash_with_namespace"),
61 QStringLiteral(
"noreply"),
62 QStringLiteral(
"randomize_replica_read"),
63 QStringLiteral(
"sort_hosts"),
64 QStringLiteral(
"support_cas"),
65 QStringLiteral(
"use_udp"),
66 QStringLiteral(
"tcp_nodelay"),
67 QStringLiteral(
"tcp_keepalive"),
69 if (map.value(flag, d->defaultConfig.value(flag,
false)).toBool()) {
75 const bool useUDP = map.value(QStringLiteral(
"use_udp"),
76 d->defaultConfig.value(QStringLiteral(
"use_udp"),
false))
80 QStringLiteral(
"connect_timeout"),
81 QStringLiteral(
"distribution"),
82 QStringLiteral(
"hash"),
83 QStringLiteral(
"number_of_replicas"),
84 QStringLiteral(
"namespace"),
85 QStringLiteral(
"retry_timeout"),
86 QStringLiteral(
"server_failure_limit"),
87 QStringLiteral(
"snd_timeout"),
88 QStringLiteral(
"socket_recv_size"),
89 QStringLiteral(
"socket_send_size"),
90 QStringLiteral(
"poll_timeout"),
91 QStringLiteral(
"io_bytes_watermark"),
92 QStringLiteral(
"io_key_prefetch"),
93 QStringLiteral(
"io_msg_watermark"),
94 QStringLiteral(
"rcv_timeout"),
96 const QString _val = map.value(opt, d->defaultConfig.value(opt)).toString();
108 "Setting up connection to memcached servers using libmemcached %s with the following "
109 "configuration string: \"%s\"",
110 memcached_lib_version(),
113 memcached_st *new_memc = memcached(configString.
constData(), configString.
size());
117 if (!serverList.
empty()) {
118 for (
const QString &server : serverList) {
123 bool isSocket =
false;
124 if (!serverParts.empty()) {
125 const auto part0 = serverParts.at(0);
126 if (!part0.isEmpty()) {
127 name = part0.toString();
130 if (serverParts.size() > 1) {
131 const auto part1 = serverParts.at(1);
132 if (!part1.isEmpty()) {
134 weight = part1.toUInt();
136 port = part1.toUInt();
139 if (!isSocket && (serverParts.size() > 2)) {
140 const auto part2 = serverParts.at(2);
141 if (!part2.isEmpty()) {
142 weight = part2.toUInt();
148 memcached_return_t rc;
150 rc = memcached_server_add_unix_socket_with_weight(
152 if (Q_LIKELY(memcached_success(rc))) {
154 "Added memcached server on socket %s with weight %u.",
160 "Failed to add memcached server on socket %s with weight %u: %s",
163 memcached_strerror(new_memc, rc));
167 rc = memcached_server_add_udp_with_weight(
170 rc = memcached_server_add_with_weight(
173 if (Q_LIKELY(memcached_success(rc))) {
175 "Added memcached server on host %s:%u with weight %u.",
182 "Failed to add memcached server on host %s:%u with weight %u: %s",
186 memcached_strerror(new_memc, rc));
192 if (Q_UNLIKELY(memcached_server_count(new_memc) == 0)) {
193 qCWarning(C_MEMCACHED,
194 "Failed to add any memcached server. Adding default server on localhost "
196 memcached_return_t rc = memcached_server_add(new_memc,
"localhost", 11211);
197 if (Q_UNLIKELY(!memcached_success(rc))) {
198 qCCritical(C_MEMCACHED,
199 "Failed to add default memcached server. Memcached plugin will not "
200 "work without a configured server! %s",
201 memcached_strerror(new_memc, rc));
202 memcached_free(new_memc);
208 d->compression = map.value(QStringLiteral(
"compression"),
209 d->defaultConfig.value(QStringLiteral(
"compression"),
false))
211 d->compressionLevel =
212 map.value(QStringLiteral(
"compression_level"),
213 d->defaultConfig.value(QStringLiteral(
"compression_level"), -1))
215 d->compressionThreshold =
216 map.value(QStringLiteral(
"compression_threshold"),
217 d->defaultConfig.value(QStringLiteral(
"compression_threshold"), 100))
219 if (d->compression) {
221 "Compression: enabled (Compression level: %i, Compression threshold: %i bytes)",
223 d->compressionThreshold);
225 qCInfo(C_MEMCACHED,
"Compression: disabled");
228 const QString encKey = map.value(QStringLiteral(
"encryption_key")).toString();
231 const memcached_return_t rt =
232 memcached_set_encoding_key(new_memc, encKeyBa.
constData(), encKeyBa.
size());
233 if (Q_LIKELY(memcached_success(rt))) {
234 qCInfo(C_MEMCACHED,
"Encryption: enabled");
236 qCWarning(C_MEMCACHED,
237 "Failed to enable encryption: %s",
238 memcached_strerror(new_memc, rt));
241 qCInfo(C_MEMCACHED,
"Encryption: disabled");
244#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
245# if LIBMEMCACHED_WITH_SASL_SUPPORT == 1
246 const QString saslUser = map.value(QStringLiteral(
"sasl_user")).toString();
247 const QString saslPass = map.value(QStringLiteral(
"sasl_password")).toString();
249 const memcached_return_t rt = memcached_set_sasl_auth_data(
251 if (Q_LIKELY(memcached_success(rt))) {
252 qCInfo(C_MEMCACHED,
"SASL authentication: enabled");
253 d->saslEnabled =
true;
255 qCWarning(C_MEMCACHED,
256 "Failed to enable SASL authentication: %s",
257 memcached_strerror(new_memc, rt));
260 qCInfo(C_MEMCACHED,
"SASL authentication: disabled");
266 memcached_free(d->memc);
276 qCCritical(C_MEMCACHED) <<
"Failed to configure the connection to the memcached server(s)";
288 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
297 MemcachedPrivate::Flags flags;
300 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
301 flags |= MemcachedPrivate::Compressed;
302 _value = qCompress(value, mcd->d_ptr->compressionLevel);
305 const memcached_return_t rt = memcached_set(mcd->d_ptr->memc,
313 const bool ok = memcached_success(rt);
316 qCWarning(C_MEMCACHED,
317 "Failed to store key \"%s\": %s",
319 memcached_strerror(mcd->d_ptr->memc, rt));
322 MemcachedPrivate::setReturnType(returnType, rt);
334 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
344 MemcachedPrivate::Flags flags;
347 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
348 flags |= MemcachedPrivate::Compressed;
349 _value = qCompress(value, mcd->d_ptr->compressionLevel);
352 const memcached_return_t rt = memcached_set_by_key(mcd->d_ptr->memc,
362 const bool ok = memcached_success(rt);
365 qCWarning(C_MEMCACHED,
366 "Failed to store key \"%s\" on group \"%s\": %s",
369 memcached_strerror(mcd->d_ptr->memc, rt));
372 MemcachedPrivate::setReturnType(returnType, rt);
383 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
392 MemcachedPrivate::Flags flags;
395 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
396 flags |= MemcachedPrivate::Compressed;
397 _value = qCompress(value, mcd->d_ptr->compressionLevel);
400 const memcached_return_t rt = memcached_add(mcd->d_ptr->memc,
408 const bool ok = memcached_success(rt);
410 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
411 qCWarning(C_MEMCACHED,
412 "Failed to add key \"%s\": %s",
414 memcached_strerror(mcd->d_ptr->memc, rt));
417 MemcachedPrivate::setReturnType(returnType, rt);
429 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
439 MemcachedPrivate::Flags flags;
442 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
443 flags |= MemcachedPrivate::Compressed;
444 _value = qCompress(value, mcd->d_ptr->compressionLevel);
447 const memcached_return_t rt = memcached_add_by_key(mcd->d_ptr->memc,
457 const bool ok = memcached_success(rt);
459 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
460 qCWarning(C_MEMCACHED,
461 "Failed to add key \"%s\" on group \"%s\": %s",
464 memcached_strerror(mcd->d_ptr->memc, rt));
467 MemcachedPrivate::setReturnType(returnType, rt);
478 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
487 MemcachedPrivate::Flags flags;
490 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
491 flags |= MemcachedPrivate::Compressed;
492 _value = qCompress(value, mcd->d_ptr->compressionLevel);
495 const memcached_return_t rt = memcached_replace(mcd->d_ptr->memc,
503 const bool ok = memcached_success(rt);
505 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
506 qCWarning(C_MEMCACHED,
507 "Failed to replace key \"%s\": %s",
509 memcached_strerror(mcd->d_ptr->memc, rt));
512 MemcachedPrivate::setReturnType(returnType, rt);
524 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
534 MemcachedPrivate::Flags flags;
537 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
538 flags |= MemcachedPrivate::Compressed;
539 _value = qCompress(value, mcd->d_ptr->compressionLevel);
542 const memcached_return_t rt = memcached_replace_by_key(mcd->d_ptr->memc,
552 const bool ok = memcached_success(rt);
554 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
555 qCWarning(C_MEMCACHED,
556 "Failed to replace key \"%s\" on group \"%s\": %s",
559 memcached_strerror(mcd->d_ptr->memc, rt));
562 MemcachedPrivate::setReturnType(returnType, rt);
574 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
581 memcached_return_t rt;
585 std::vector<const char *> keys;
586 std::vector<size_t> sizes;
588 sizes.push_back(_key.
size());
589 rt = memcached_mget(mcd->d_ptr->memc, &keys[0], &sizes[0], keys.size());
591 if (memcached_success(rt)) {
592 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
594 retData =
QByteArray(memcached_result_value(result), memcached_result_length(result));
596 *
cas = memcached_result_cas(result);
598 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
599 if (flags.testFlag(MemcachedPrivate::Compressed)) {
600 retData = qUncompress(retData);
605 memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
607 memcached_result_free(result);
610 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
611 qCWarning(C_MEMCACHED,
612 "Failed to get data for key \"%s\": %s",
614 memcached_strerror(mcd->d_ptr->memc, rt));
617 MemcachedPrivate::setReturnType(returnType, rt);
630 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
637 memcached_return_t rt;
642 std::vector<const char *> keys;
643 std::vector<size_t> sizes;
645 sizes.push_back(_key.
size());
646 rt = memcached_mget_by_key(mcd->d_ptr->memc,
653 if (memcached_success(rt)) {
654 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
656 retData =
QByteArray(memcached_result_value(result), memcached_result_length(result));
658 *
cas = memcached_result_cas(result);
660 MemcachedPrivate::Flags flags = MemcachedPrivate::Flags(memcached_result_flags(result));
661 if (flags.testFlag(MemcachedPrivate::Compressed)) {
662 retData = qUncompress(retData);
667 memcached_fetch_result(mcd->d_ptr->memc, NULL, NULL);
669 memcached_result_free(result);
672 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
673 qCWarning(C_MEMCACHED,
674 "Failed to get data for key \"%s\" on group \"%s\": %s",
677 memcached_strerror(mcd->d_ptr->memc, rt));
680 MemcachedPrivate::setReturnType(returnType, rt);
688 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
697 const memcached_return_t rt =
698 memcached_delete(mcd->d_ptr->memc, _key.
constData(), _key.
size(), 0);
700 const bool ok = memcached_success(rt);
702 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
703 qCWarning(C_MEMCACHED,
704 "Failed to remove data for key \"%s\": %s",
706 memcached_strerror(mcd->d_ptr->memc, rt));
709 MemcachedPrivate::setReturnType(returnType, rt);
719 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
729 const memcached_return_t rt = memcached_delete_by_key(mcd->d_ptr->memc,
736 const bool ok = memcached_success(rt);
738 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
739 qCWarning(C_MEMCACHED,
740 "Failed to remove data for key \"%s\" on group \"%s\": %s",
743 memcached_strerror(mcd->d_ptr->memc, rt));
746 MemcachedPrivate::setReturnType(returnType, rt);
754 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
763 const memcached_return_t rt = memcached_exist(mcd->d_ptr->memc, _key.
constData(), _key.
size());
765 const bool ok = memcached_success(rt);
767 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
768 qCWarning(C_MEMCACHED,
769 "Failed to check existence of key \"%s\": %s",
771 memcached_strerror(mcd->d_ptr->memc, rt));
774 MemcachedPrivate::setReturnType(returnType, rt);
784 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
794 const memcached_return_t rt = memcached_exist_by_key(
797 const bool ok = memcached_success(rt);
799 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
800 qCWarning(C_MEMCACHED,
801 "Failed to check existence of key \"%s\" in group \"%s\"",
806 MemcachedPrivate::setReturnType(returnType, rt);
817 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
826 const memcached_return_t rt =
827 memcached_increment(mcd->d_ptr->memc, _key.
constData(), _key.
size(), offset, value);
829 const bool ok = memcached_success(rt);
831 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
832 qCWarning(C_MEMCACHED,
833 "Failed to increment key \"%s\" by %u: %s",
836 memcached_strerror(mcd->d_ptr->memc, rt));
839 MemcachedPrivate::setReturnType(returnType, rt);
851 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
861 const memcached_return_t rt = memcached_increment_by_key(mcd->d_ptr->memc,
869 const bool ok = memcached_success(rt);
871 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
872 qCWarning(C_MEMCACHED,
873 "Failed to increment \"%s\" key on group \"%s\" by %lu: %s",
877 memcached_strerror(mcd->d_ptr->memc, rt));
880 MemcachedPrivate::setReturnType(returnType, rt);
893 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
902 const memcached_return_t rt = memcached_increment_with_initial(
903 mcd->d_ptr->memc, _key.
constData(), _key.
size(), offset, initial, expiration, value);
905 const bool ok = memcached_success(rt);
908 qCWarning(C_MEMCACHED,
909 "Failed to increment or initialize key \"%s\" by offset %lu or initial %lu: %s",
913 memcached_strerror(mcd->d_ptr->memc, rt));
916 MemcachedPrivate::setReturnType(returnType, rt);
930 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
940 const memcached_return_t rt = memcached_increment_with_initial_by_key(mcd->d_ptr->memc,
950 const bool ok = memcached_success(rt);
952 qCWarning(C_MEMCACHED,
953 "Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or "
959 memcached_strerror(mcd->d_ptr->memc, rt));
962 MemcachedPrivate::setReturnType(returnType, rt);
973 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
982 const memcached_return_t rt =
983 memcached_decrement(mcd->d_ptr->memc, _key.
constData(), _key.
size(), offset, value);
985 const bool ok = memcached_success(rt);
987 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
988 qCWarning(C_MEMCACHED,
989 "Failed to decrement key \"%s\" by %u: %s",
992 memcached_strerror(mcd->d_ptr->memc, rt));
995 MemcachedPrivate::setReturnType(returnType, rt);
1007 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1017 const memcached_return_t rt = memcached_decrement_by_key(mcd->d_ptr->memc,
1025 const bool ok = memcached_success(rt);
1027 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
1028 qCWarning(C_MEMCACHED,
1029 "Failed to decrement \"%s\" key on group \"%s\" by %lu: %s",
1033 memcached_strerror(mcd->d_ptr->memc, rt));
1036 MemcachedPrivate::setReturnType(returnType, rt);
1049 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1058 const memcached_return_t rt = memcached_decrement_with_initial(
1059 mcd->d_ptr->memc, _key.
constData(), _key.
size(), offset, initial, expiration, value);
1061 const bool ok = memcached_success(rt);
1064 qCWarning(C_MEMCACHED,
1065 "Failed to decrement or initialize key \"%s\" by offset %lu or initial %lu: %s",
1069 memcached_strerror(mcd->d_ptr->memc, rt));
1072 MemcachedPrivate::setReturnType(returnType, rt);
1086 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1096 const memcached_return_t rt = memcached_decrement_with_initial_by_key(mcd->d_ptr->memc,
1106 const bool ok = memcached_success(rt);
1108 qCWarning(C_MEMCACHED,
1109 "Failed to increment or initialize key \"%s\" in group \"%s\" by offset %lu or "
1115 memcached_strerror(mcd->d_ptr->memc, rt));
1118 MemcachedPrivate::setReturnType(returnType, rt);
1130 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1139 MemcachedPrivate::Flags flags;
1142 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
1143 flags |= MemcachedPrivate::Compressed;
1144 _value = qCompress(value, mcd->d_ptr->compressionLevel);
1147 const memcached_return_t rt = memcached_cas(mcd->d_ptr->memc,
1156 const bool ok = memcached_success(rt);
1158 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1159 qCWarning(C_MEMCACHED,
1160 "Failed to compare and set (cas) key \"%s\": %s",
1162 memcached_strerror(mcd->d_ptr->memc, rt));
1165 MemcachedPrivate::setReturnType(returnType, rt);
1178 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1188 MemcachedPrivate::Flags flags;
1191 if (mcd->d_ptr->compression && (_value.
size() > mcd->d_ptr->compressionThreshold)) {
1192 flags |= MemcachedPrivate::Compressed;
1193 _value = qCompress(value, mcd->d_ptr->compressionLevel);
1196 const memcached_return_t rt = memcached_cas_by_key(mcd->d_ptr->memc,
1207 const bool ok = memcached_success(rt);
1209 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1210 qCWarning(C_MEMCACHED,
1211 "Failed to compare and set (cas) key \"%s\" in group \"%s\": %s",
1214 memcached_strerror(mcd->d_ptr->memc, rt));
1217 MemcachedPrivate::setReturnType(returnType, rt);
1225 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1232 const memcached_return_t rt = memcached_flush_buffers(mcd->d_ptr->memc);
1234 const bool ok = memcached_success(rt);
1238 C_MEMCACHED,
"Failed to flush buffers: %s", memcached_strerror(mcd->d_ptr->memc, rt));
1241 MemcachedPrivate::setReturnType(returnType, rt);
1249 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1256 const memcached_return_t rt = memcached_flush(mcd->d_ptr->memc, expiration);
1258 const bool ok = memcached_success(rt);
1261 qCWarning(C_MEMCACHED,
1262 "Failed to wipe clean (flush) server content: %s",
1263 memcached_strerror(mcd->d_ptr->memc, rt));
1266 MemcachedPrivate::setReturnType(returnType, rt);
1278 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1286 qCWarning(C_MEMCACHED,
"Can not get multiple values without a list of keys.");
1293 std::vector<char *> _keys;
1294 _keys.reserve(keys.
size());
1295 std::vector<size_t> _keysSizes;
1296 _keysSizes.reserve(keys.
size());
1298 for (
const QString &key : keys) {
1300 char *data =
new char[_key.
size() + 1];
1301 qstrcpy(data, _key.
data());
1302 _keys.push_back(data);
1303 _keysSizes.push_back(_key.
size());
1306 memcached_return_t rt;
1309 rt = memcached_mget(mcd->d_ptr->memc, &_keys[0], &_keysSizes[0], _keys.size());
1311 if (memcached_success(rt)) {
1314 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1315 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1318 memcached_result_key_length(result));
1319 QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1321 casValues->
insert(rk, memcached_result_cas(result));
1323 MemcachedPrivate::Flags flags =
1324 MemcachedPrivate::Flags(memcached_result_flags(result));
1325 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1326 rd = qUncompress(rd);
1330 memcached_result_free(result);
1334 for (
char *c : _keys) {
1339 qCWarning(C_MEMCACHED,
1340 "Failed to get values for multiple keys: %s",
1341 memcached_strerror(mcd->d_ptr->memc, rt));
1344 MemcachedPrivate::setReturnType(returnType, rt);
1357 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1365 qCWarning(C_MEMCACHED,
1366 "Can not get multiple values from specific server when groupKey is empty.");
1374 qCWarning(C_MEMCACHED,
"Can not get multiple values without a list of keys.");
1383 std::vector<char *> _keys;
1384 _keys.reserve(keys.
size());
1385 std::vector<size_t> _keysSizes;
1386 _keysSizes.reserve(keys.
size());
1388 for (
const QString &key : keys) {
1390 char *data =
new char[_key.
size() + 1];
1391 strcpy(data, _key.
data());
1392 _keys.push_back(data);
1393 _keysSizes.push_back(_key.
size());
1396 memcached_return_t rt;
1399 rt = memcached_mget_by_key(mcd->d_ptr->memc,
1406 if (memcached_success(rt)) {
1409 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1410 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc, NULL, &rt);
1413 memcached_result_key_length(result));
1414 QByteArray rd(memcached_result_value(result), memcached_result_length(result));
1416 casValues->
insert(rk, memcached_result_cas(result));
1418 MemcachedPrivate::Flags flags =
1419 MemcachedPrivate::Flags(memcached_result_flags(result));
1420 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1421 rd = qUncompress(rd);
1425 memcached_result_free(result);
1429 for (
char *c : _keys) {
1434 qCWarning(C_MEMCACHED,
1435 "Failed to get values for multiple keys in group \"%s\": %s",
1437 memcached_strerror(mcd->d_ptr->memc, rt));
1440 MemcachedPrivate::setReturnType(returnType, rt);
1448 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1457 const memcached_return_t rt =
1458 memcached_touch(mcd->d_ptr->memc, _key.
constData(), _key.
size(), expiration);
1460 const bool ok = memcached_success(rt);
1463 qCWarning(C_MEMCACHED,
1464 "Failed to touch key \"%s\" with new expiration time %lu: %s",
1467 memcached_strerror(mcd->d_ptr->memc, rt));
1470 MemcachedPrivate::setReturnType(returnType, rt);
1481 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1491 const memcached_return_t rt = memcached_touch_by_key(mcd->d_ptr->memc,
1498 const bool ok = memcached_success(rt);
1501 qCWarning(C_MEMCACHED,
1502 "Failed to touch key \"%s\" in group \"%s\" with new expiration time %lu: %s",
1506 memcached_strerror(mcd->d_ptr->memc, rt));
1509 MemcachedPrivate::setReturnType(returnType, rt);
1518 return c->
translate(
"Cutelyst::Memcached",
"The request was successfully executed.");
1520 return c->
translate(
"Cutelyst::Memcached",
1521 "An unknown failure has occurred in the Memcached server.");
1523 return c->
translate(
"Cutelyst::Memcached",
"A DNS failure has occurred.");
1526 "Cutelyst::Memcached",
1527 "An unknown error has occurred while trying to connect to a Memcached server.");
1529 return c->
translate(
"Cutelyst::Memcached",
1530 "An error has occurred while trying to write to a Memcached server.");
1532 return c->
translate(
"Cutelyst::Memcached",
1533 "An error has occurred while trying to read from a Memcached server.");
1536 "Cutelyst::Memcached",
1537 "An unknown error has occurred while trying to read from a Memcached server. This only "
1538 "occures when either there is a bug in the server, or in rare cases where an ethernet "
1539 "NIC is reporting dubious information.");
1541 return c->
translate(
"Cutelyst::Memcached",
1542 "An unknown error has occurred in the Memcached protocol.");
1544 return c->
translate(
"Cutelyst::Memcached",
1545 "An unknown Memcached client error has occurred internally.");
1547 return c->
translate(
"Cutelyst::Memcached",
1548 "An unknown error has occurred in the Memcached server.");
1550 return c->
translate(
"Cutelyst::Memcached",
"A general error occurred.");
1552 return c->
translate(
"Cutelyst::Memcached",
"The data for the given key alrey exists.");
1554 return c->
translate(
"Cutelyst::Memcached",
1555 "The data requested with the key given was not found.");
1557 return c->
translate(
"Cutelyst::Memcached",
"The request to store an object failed.");
1559 return c->
translate(
"Cutelyst::Memcached",
1560 "The requested object has been successfully stored on the server.");
1562 return c->
translate(
"Cutelyst::Memcached",
"The object requested was not found.");
1564 return c->
translate(
"Cutelyst::Memcached",
1565 "An error has occurred while trying to allocate memory.");
1567 return c->
translate(
"Cutelyst::Memcached",
1568 "The read operation was only partcially successful.");
1570 return c->
translate(
"Cutelyst::Memcached",
1571 "A multi request has been made, and some underterminate number of "
1572 "errors have occurred.");
1574 return c->
translate(
"Cutelyst::Memcached",
1575 "No servers have been added to the Memcached plugin.");
1578 "Cutelyst::Memcached",
1579 "The Memcached server has completed returning all of the objects requested.");
1581 return c->
translate(
"Cutelyst::Memcached",
1582 "The object requested by the key has been deleted.");
1584 return c->
translate(
"Cutelyst::Memcached",
1585 "A “stat” command has been returned in the protocol.");
1587 return c->
translate(
"Cutelyst::Memcached",
1588 "An error has occurred in the driver which has set errno.");
1590 return c->
translate(
"Cutelyst::Memcached",
1591 "The given method is not supported in the Memcached server.");
1593 return c->
translate(
"Cutelyst::Memcached",
1594 "A request has been made, but the Memcached server has not finished "
1595 "the fetch of the last request.");
1597 return c->
translate(
"Cutelyst::Memcached",
"The operation has timed out.");
1599 return c->
translate(
"Cutelyst::Memcached",
"The request has been buffered.");
1601 return c->
translate(
"Cutelyst::Memcached",
"The key provided is not a valid key.");
1604 "Cutelyst::Memcached",
1605 "The Memcached server you are connecting to has an invalid protocol. Most likely you "
1606 "are connecting to an older server that does not speak the binary protocol.");
1608 return c->
translate(
"Cutelyst::Memcached",
1609 "The requested Memcached server has been marked dead.");
1611 return c->
translate(
"Cutelyst::Memcached",
1612 "The Memcached server you are communicating with has a stat key which "
1613 "has not be defined in the protocol.");
1615 return c->
translate(
"Cutelyst::Memcached",
1616 "Item is too large for the Memcached server to store.");
1618 return c->
translate(
"Cutelyst::Memcached",
1619 "The arguments supplied to the given function were not valid.");
1622 "Cutelyst::Memcached",
1623 "The key that has been provided is too large for the given Memcached server.");
1625 return c->
translate(
"Cutelyst::Memcached",
1626 "An unknown issue has occurred during SASL authentication.");
1628 return c->
translate(
"Cutelyst::Memcached",
1629 "The credentials provided are not valid for this Memcached server.");
1631 return c->
translate(
"Cutelyst::Memcached",
"Authentication has been paused.");
1634 "Cutelyst::Memcached",
1635 "An error has occurred while trying to parse the configuration string.");
1637 return c->
translate(
"Cutelyst::Memcached",
1638 "An error has occurred in parsing the configuration string.");
1640 return c->
translate(
"Cutelyst::Memcached",
1641 "The method that was requested has been deprecated.");
1644 "Cutelyst::Memcached",
1645 "The Cutelyst Memcached plugin has not been registered to the application.");
1647 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occurred.");
1702 case MEMCACHED_IN_PROGRESS:
return Memcached::InProgress;
1703 case MEMCACHED_SERVER_TEMPORARILY_DISABLED:
return Memcached::ServerTemporaryDisabled;
1704 case MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE:
return Memcached::ServerMemoryAllocationFailure;
1705 case MEMCACHED_MAXIMUM_RETURN:
return Memcached::MaximumReturn;
1714 *rt1 = MemcachedPrivate::returnTypeConvert(rt2);
1718#include "moc_memcached.cpp"
The Cutelyst Application.
Engine * engine() const noexcept
void loadTranslations(const QString &filename, const QString &directory=QString(), const QString &prefix=QString(), const QString &suffix=QString())
void postForked(Cutelyst::Application *app)
QString translate(const char *context, const char *sourceText, const char *disambiguation=nullptr, int n=-1) const
QVariantMap config(const QString &entity) const
user configuration for the application
Cutelyst Memcached plugin.
static bool replaceByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool existByKey(const QString &groupKey, const QString &key, MemcachedReturnType *returnType=nullptr)
static bool incrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool add(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
@ MemoryAllocationFailure
static QByteArray get(const QString &key, uint64_t *cas=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 bool increment(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
virtual bool setup(Application *app) override
static bool flush(time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool exist(const QString &key, MemcachedReturnType *returnType=nullptr)
static bool decrementByKey(const QString &groupKey, const QString &key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool removeByKey(const QString &groupKey, const QString &key, 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 cas(const QString &key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
static bool touch(const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
static QHash< QString, QByteArray > mgetByKey(const QString &groupKey, const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
static bool flushBuffers(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)
virtual ~Memcached() override
static const time_t expirationNotAdd
static bool set(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
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 decrement(const QString &key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static QString errorString(Context *c, MemcachedReturnType rt)
static bool touchByKey(const QString &groupKey, const QString &key, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool decrementWithInitial(const QString &key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
void setDefaultConfig(const QVariantMap &defaultConfig)
static bool setByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static QHash< QString, QByteArray > mget(const QStringList &keys, QHash< QString, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
static bool remove(const QString &key, MemcachedReturnType *returnType=nullptr)
static bool replace(const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool addByKey(const QString &groupKey, const QString &key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static QByteArray getByKey(const QString &groupKey, const QString &key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
Memcached(Application *parent)
static QVersionNumber libMemcachedVersion()
Returns the version of the currently used libmemcached.
Plugin(Application *parent)
The Cutelyst namespace holds all public Cutelyst API.
const char * constData() const const
iterator insert(const Key &key, const T &value)
void push_back(const T &value)
QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject * parent() const const
QString fromUtf8(const char *str, int size)
bool isEmpty() const const
QString & replace(int position, int n, QChar after)
bool startsWith(const QString &s, Qt::CaseSensitivity cs) const const
QString toUpper() const const
QByteArray toUtf8() const const
QString join(const QString &separator) const const
QList< QStringView > split(QStringView sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QVersionNumber fromString(const QString &string, int *suffixIndex)