6#include "memcached_p.h"
8#include <Cutelyst/Application>
9#include <Cutelyst/Context>
10#include <Cutelyst/Engine>
12#include <QLoggingCategory>
15Q_LOGGING_CATEGORY(C_MEMCACHED,
"cutelyst.plugin.memcached", QtWarningMsg)
20static thread_local Memcached *mcd =
nullptr;
23 static_cast<std::chrono::seconds::rep
>(MEMCACHED_EXPIRATION_NOT_ADD)};
27 , d_ptr(new MemcachedPrivate)
36 d->defaultConfig = defaultConfig;
43 const QVariantMap map = app->
engine()->
config(u
"Cutelyst_Memcached_Plugin"_qs);
46 const QStringList serverList =
47 map.value(u
"servers"_qs, d->defaultConfig.value(u
"servers"_qs)).toString().split(u
';');
49 if (serverList.empty()) {
50 config.push_back(u
"--SERVER=localhost"_qs);
53 for (
const QString &flag : {u
"verify_key"_qs,
54 u
"remove_failed_servers"_qs,
55 u
"binary_protocol"_qs,
56 u
"buffer_requests"_qs,
57 u
"hash_with_namespace"_qs,
59 u
"randomize_replica_read"_qs,
64 u
"tcp_keepalive"_qs}) {
65 if (map.value(flag, d->defaultConfig.value(flag,
false)).toBool()) {
66 const QString flagStr = u
"--" + flag.toUpper().replace(u
'_', u
'-');
67 config.push_back(flagStr);
72 map.value(u
"use_udp"_qs, d->defaultConfig.value(u
"use_udp"_qs,
false)).toBool();
74 for (
const QString &opt : {
75 u
"connect_timeout"_qs,
78 u
"number_of_replicas"_qs,
81 u
"server_failure_limit"_qs,
83 u
"socket_recv_size"_qs,
84 u
"socket_send_size"_qs,
86 u
"io_bytes_watermark"_qs,
87 u
"io_key_prefetch"_qs,
88 u
"io_msg_watermark"_qs,
91 const QString _val = map.value(opt, d->defaultConfig.value(opt)).toString();
92 if (!_val.isEmpty()) {
93 const QString optStr = u
"--" + opt.toUpper().replace(u
'_', u
'-') + u
'=' + _val;
94 config.push_back(optStr);
98 const QByteArray configString = config.join(u
' ').toUtf8();
102 qCInfo(C_MEMCACHED) <<
"Setting up connection to memcached servers using libmemcached"
103 << memcached_lib_version()
104 <<
"with the following configuration string:" << configString;
106 memcached_st *new_memc = memcached(configString.constData(), configString.size());
110 if (!serverList.empty()) {
111 for (
const QString &server : serverList) {
112 const auto serverParts = QStringView(server).split(u
',');
114 uint16_t port = MemcachedPrivate::defaultPort;
116 bool isSocket =
false;
117 if (!serverParts.empty()) {
118 const auto part0 = serverParts.at(0);
119 if (!part0.isEmpty()) {
120 name = part0.toString();
121 isSocket = name.startsWith(u
'/');
123 if (serverParts.size() > 1) {
124 const auto part1 = serverParts.at(1);
125 if (!part1.isEmpty()) {
127 weight = part1.toUInt();
129 port = part1.toUInt();
132 if (!isSocket && (serverParts.size() > 2)) {
133 const auto part2 = serverParts.at(2);
134 if (!part2.isEmpty()) {
135 weight = part2.toUInt();
140 if (!name.isEmpty()) {
141 memcached_return_t rc{MEMCACHED_FAILURE};
143 rc = memcached_server_add_unix_socket_with_weight(
144 new_memc, name.toUtf8().constData(), weight);
145 if (Q_LIKELY(memcached_success(rc))) {
146 qCInfo(C_MEMCACHED) <<
"Added memcached server on socket" << name
147 <<
"with weight" << weight;
149 qCWarning(C_MEMCACHED).nospace()
150 <<
"Failed to add memcached server on socket " << name
151 <<
" with weight " << weight <<
": "
152 << memcached_strerror(new_memc, rc);
156 rc = memcached_server_add_udp_with_weight(
157 new_memc, name.toUtf8().constData(), port, weight);
159 rc = memcached_server_add_with_weight(
160 new_memc, name.toUtf8().constData(), port, weight);
162 if (Q_LIKELY(memcached_success(rc))) {
163 qCInfo(C_MEMCACHED).nospace().noquote()
164 <<
"Added memcached server on host " << name <<
":" << port
165 <<
" with weight" << weight;
167 qCWarning(C_MEMCACHED).nospace().noquote()
168 <<
"Failed to add memcached server no host " << name <<
":" << port
169 <<
" with weight " << weight <<
": "
170 << memcached_strerror(new_memc, rc);
176 if (Q_UNLIKELY(memcached_server_count(new_memc) == 0)) {
177 qCWarning(C_MEMCACHED)
178 <<
"Failed to add any memcached server. Adding default server on localhost"
180 memcached_return_t rc =
181 memcached_server_add(new_memc,
"localhost", MemcachedPrivate::defaultPort);
182 if (Q_UNLIKELY(!memcached_success(rc))) {
183 qCCritical(C_MEMCACHED)
184 <<
"Failed to add default memcached server. Memcached plugin will not"
185 <<
"work without a configured server!" << memcached_strerror(new_memc, rc);
186 memcached_free(new_memc);
193 map.value(u
"compression"_qs, d->defaultConfig.value(u
"compression"_qs,
false)).toBool();
194 d->compressionLevel =
195 map.value(u
"compression_level"_qs, d->defaultConfig.value(u
"compression_level"_qs, -1))
197 d->compressionThreshold =
198 map.value(u
"compression_threshold"_qs,
199 d->defaultConfig.value(u
"compression_threshold"_qs,
200 MemcachedPrivate::defaultCompressionThreshold))
202 if (d->compression) {
203 qCInfo(C_MEMCACHED).nospace()
204 <<
"Compression: enabled (Compression level: " << d->compressionLevel
205 <<
", Compression threshold: " << d->compressionThreshold <<
" bytes";
207 qCInfo(C_MEMCACHED) <<
"Compression: disabled";
210 const QString encKey = map.value(u
"encryption_key"_qs).toString();
211 if (!encKey.isEmpty()) {
212 const QByteArray encKeyBa = encKey.toUtf8();
213 const memcached_return_t rt =
214 memcached_set_encoding_key(new_memc, encKeyBa.constData(), encKeyBa.size());
215 if (Q_LIKELY(memcached_success(rt))) {
216 qCInfo(C_MEMCACHED) <<
"Encryption: enabled";
218 qCWarning(C_MEMCACHED)
219 <<
"Failed to enable encryption:" << memcached_strerror(new_memc, rt);
222 qCInfo(C_MEMCACHED) <<
"Encryption: disabled";
225#ifdef LIBMEMCACHED_WITH_SASL_SUPPORT
226# if LIBMEMCACHED_WITH_SASL_SUPPORT == 1
227 const QString saslUser = map.value(u
"sasl_user"_qs).toString();
228 const QString saslPass = map.value(u
"sasl_password"_qs).toString();
229 if (!saslUser.isEmpty() && !saslPass.isEmpty()) {
230 const memcached_return_t rt = memcached_set_sasl_auth_data(
231 new_memc, saslUser.toUtf8().constData(), saslPass.toUtf8().constData());
232 if (Q_LIKELY(memcached_success(rt))) {
233 qCInfo(C_MEMCACHED) <<
"SASL authentication: enabled";
234 d->saslEnabled =
true;
236 qCWarning(C_MEMCACHED)
237 <<
"Failed to enable SASL authentication:" << memcached_strerror(new_memc, rt);
240 qCInfo(C_MEMCACHED) <<
"SASL authentication: disabled";
246 memcached_free(d->memc);
256 qCCritical(C_MEMCACHED) <<
"Failed to configure the connection to the memcached server(s)";
263 const QByteArray &value,
268 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
275 MemcachedPrivate::Flags flags;
276 QByteArray _value = value;
278 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
279 flags |= MemcachedPrivate::Compressed;
280 _value = qCompress(value, mcd->d_ptr->compressionLevel);
283 const memcached_return_t rt = memcached_set(mcd->d_ptr->memc,
291 const bool ok = memcached_success(rt);
294 qCWarning(C_MEMCACHED).nospace()
295 <<
"Failed to store key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
298 MemcachedPrivate::setReturnType(returnType, rt);
305 const QByteArray &value,
310 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
317 MemcachedPrivate::Flags flags;
318 QByteArray _value = value;
320 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
321 flags |= MemcachedPrivate::Compressed;
322 _value = qCompress(value, mcd->d_ptr->compressionLevel);
325 const memcached_return_t rt = memcached_set_by_key(mcd->d_ptr->memc,
326 groupKey.constData(),
335 const bool ok = memcached_success(rt);
338 qCWarning(C_MEMCACHED).nospace()
339 <<
"Failed to store key " << key <<
" on group " << groupKey <<
": "
340 << memcached_strerror(mcd->d_ptr->memc, rt);
343 MemcachedPrivate::setReturnType(returnType, rt);
349 const QByteArray &value,
354 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
361 MemcachedPrivate::Flags flags;
362 QByteArray _value = value;
364 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
365 flags |= MemcachedPrivate::Compressed;
366 _value = qCompress(value, mcd->d_ptr->compressionLevel);
369 const memcached_return_t rt = memcached_add(mcd->d_ptr->memc,
377 const bool ok = memcached_success(rt);
379 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
380 qCWarning(C_MEMCACHED).nospace()
381 <<
"Failed to add key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
384 MemcachedPrivate::setReturnType(returnType, rt);
391 const QByteArray &value,
396 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
403 MemcachedPrivate::Flags flags;
404 QByteArray _value = value;
406 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
407 flags |= MemcachedPrivate::Compressed;
408 _value = qCompress(value, mcd->d_ptr->compressionLevel);
411 const memcached_return_t rt = memcached_add_by_key(mcd->d_ptr->memc,
412 groupKey.constData(),
421 const bool ok = memcached_success(rt);
423 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
424 qCWarning(C_MEMCACHED).nospace() <<
"Failed to add key " << key <<
" on group " << groupKey
425 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
428 MemcachedPrivate::setReturnType(returnType, rt);
434 const QByteArray &value,
439 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
446 MemcachedPrivate::Flags flags;
447 QByteArray _value = value;
449 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
450 flags |= MemcachedPrivate::Compressed;
451 _value = qCompress(value, mcd->d_ptr->compressionLevel);
454 const memcached_return_t rt = memcached_replace(mcd->d_ptr->memc,
462 const bool ok = memcached_success(rt);
464 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
465 qCWarning(C_MEMCACHED).nospace()
466 <<
"Failed to replace key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
469 MemcachedPrivate::setReturnType(returnType, rt);
476 const QByteArray &value,
481 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
488 MemcachedPrivate::Flags flags;
489 QByteArray _value = value;
491 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
492 flags |= MemcachedPrivate::Compressed;
493 _value = qCompress(value, mcd->d_ptr->compressionLevel);
496 const memcached_return_t rt = memcached_replace_by_key(mcd->d_ptr->memc,
497 groupKey.constData(),
506 const bool ok = memcached_success(rt);
508 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
509 qCWarning(C_MEMCACHED).nospace()
510 <<
"Failed to replace key " << key <<
" on group " << groupKey <<
": "
511 << memcached_strerror(mcd->d_ptr->memc, rt);
514 MemcachedPrivate::setReturnType(returnType, rt);
526 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
533 memcached_return_t rt{MEMCACHED_FAILURE};
536 std::vector<const char *> keys;
537 std::vector<size_t> sizes;
538 keys.push_back(key.constData());
539 sizes.push_back(key.size());
540 rt = memcached_mget(mcd->d_ptr->memc, &keys[0], &sizes[0], keys.size());
542 if (memcached_success(rt)) {
543 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
546 QByteArray(memcached_result_value(result),
547 static_cast<QByteArray::size_type
>(memcached_result_length(result)));
549 *
cas = memcached_result_cas(result);
551 MemcachedPrivate::Flags flags{memcached_result_flags(result)};
552 if (flags.testFlag(MemcachedPrivate::Compressed)) {
553 retData = qUncompress(retData);
558 memcached_fetch_result(mcd->d_ptr->memc,
nullptr,
nullptr);
560 memcached_result_free(result);
563 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
564 qCWarning(C_MEMCACHED).nospace() <<
"Failed to get data for key " << key <<
": "
565 << memcached_strerror(mcd->d_ptr->memc, rt);
568 MemcachedPrivate::setReturnType(returnType, rt);
581 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
590 std::vector<const char *> keys;
591 std::vector<size_t> sizes;
592 keys.push_back(key.constData());
593 sizes.push_back(key.size());
594 memcached_return_t rt = memcached_mget_by_key(
595 mcd->d_ptr->memc, groupKey.constData(), groupKey.size(), &keys[0], &sizes[0], keys.size());
597 if (memcached_success(rt)) {
598 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
601 QByteArray(memcached_result_value(result),
602 static_cast<QByteArray::size_type
>(memcached_result_length(result)));
604 *
cas = memcached_result_cas(result);
606 const MemcachedPrivate::Flags flags{memcached_result_flags(result)};
607 if (flags.testFlag(MemcachedPrivate::Compressed)) {
608 retData = qUncompress(retData);
613 memcached_fetch_result(mcd->d_ptr->memc,
nullptr,
nullptr);
615 memcached_result_free(result);
618 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
619 qCWarning(C_MEMCACHED).nospace()
620 <<
"Failed to get data for key " << key <<
" on group " << groupKey <<
": "
621 << memcached_strerror(mcd->d_ptr->memc, rt);
624 MemcachedPrivate::setReturnType(returnType, rt);
632 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
639 const memcached_return_t rt =
640 memcached_delete(mcd->d_ptr->memc, key.constData(), key.size(), 0);
642 const bool ok = memcached_success(rt);
644 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
645 qCWarning(C_MEMCACHED).nospace() <<
"Failed to remove data for key " << key <<
": "
646 << memcached_strerror(mcd->d_ptr->memc, rt);
649 MemcachedPrivate::setReturnType(returnType, rt);
659 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
666 const memcached_return_t rt = memcached_delete_by_key(
667 mcd->d_ptr->memc, groupKey.constData(), groupKey.size(), key.constData(), key.size(), 0);
669 const bool ok = memcached_success(rt);
671 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
672 qCWarning(C_MEMCACHED).nospace()
673 <<
"Failed to remove data for key " << key <<
" on group " << groupKey <<
": "
674 << memcached_strerror(mcd->d_ptr->memc, rt);
677 MemcachedPrivate::setReturnType(returnType, rt);
685 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
692 const memcached_return_t rt = memcached_exist(mcd->d_ptr->memc, key.constData(), key.size());
694 const bool ok = memcached_success(rt);
696 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
697 qCWarning(C_MEMCACHED).nospace() <<
"Failed to check existence of key " << key <<
": "
698 << memcached_strerror(mcd->d_ptr->memc, rt);
701 MemcachedPrivate::setReturnType(returnType, rt);
711 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
718 const memcached_return_t rt = memcached_exist_by_key(
719 mcd->d_ptr->memc, groupKey.constData(), groupKey.size(), key.constData(), key.size());
721 const bool ok = memcached_success(rt);
723 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
724 qCWarning(C_MEMCACHED).nospace()
725 <<
"Failed to check existence of key " << key <<
" in group " << groupKey <<
": "
726 << memcached_strerror(mcd->d_ptr->memc, rt);
729 MemcachedPrivate::setReturnType(returnType, rt);
740 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
747 const memcached_return_t rt =
748 memcached_increment(mcd->d_ptr->memc, key.constData(), key.size(), offset, value);
750 const bool ok = memcached_success(rt);
752 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
753 qCWarning(C_MEMCACHED).nospace() <<
"Failed to increment key " << key <<
" by " << offset
754 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
757 MemcachedPrivate::setReturnType(returnType, rt);
769 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
776 const memcached_return_t rt = memcached_increment_by_key(mcd->d_ptr->memc,
777 groupKey.constData(),
784 const bool ok = memcached_success(rt);
786 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
787 qCWarning(C_MEMCACHED).nospace()
788 <<
"Failed to increment key " << key <<
" in group " << groupKey <<
" by " << offset
789 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
792 MemcachedPrivate::setReturnType(returnType, rt);
805 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
812 const memcached_return_t rt = memcached_increment_with_initial(
813 mcd->d_ptr->memc, key.constData(), key.size(), offset, initial, expiration, value);
815 const bool ok = memcached_success(rt);
818 qCWarning(C_MEMCACHED).nospace()
819 <<
"Failed to increment or initialize key " << key <<
" by offset " << offset
820 <<
" or initial " << initial <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
823 MemcachedPrivate::setReturnType(returnType, rt);
837 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
844 const memcached_return_t rt = memcached_increment_with_initial_by_key(mcd->d_ptr->memc,
845 groupKey.constData(),
854 const bool ok = memcached_success(rt);
856 qCWarning(C_MEMCACHED).nospace()
857 <<
"Failed to increment or initializes key " << key <<
" in group " << groupKey
858 <<
" by offset " << offset <<
" or initial " << initial <<
": "
859 << memcached_strerror(mcd->d_ptr->memc, rt);
862 MemcachedPrivate::setReturnType(returnType, rt);
873 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
880 const memcached_return_t rt =
881 memcached_decrement(mcd->d_ptr->memc, key.constData(), key.size(), offset, value);
883 const bool ok = memcached_success(rt);
885 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
886 qCWarning(C_MEMCACHED).nospace() <<
"Failed to decrement key " << key <<
" by " << offset
887 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
890 MemcachedPrivate::setReturnType(returnType, rt);
902 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
909 const memcached_return_t rt = memcached_decrement_by_key(mcd->d_ptr->memc,
910 groupKey.constData(),
917 const bool ok = memcached_success(rt);
919 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
920 qCWarning(C_MEMCACHED).nospace()
921 <<
"Failed to decrement key " << key <<
" in group " << groupKey <<
" by " << offset
922 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
925 MemcachedPrivate::setReturnType(returnType, rt);
938 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
945 const memcached_return_t rt = memcached_decrement_with_initial(
946 mcd->d_ptr->memc, key.constData(), key.size(), offset, initial, expiration, value);
948 const bool ok = memcached_success(rt);
951 qCWarning(C_MEMCACHED).nospace()
952 <<
"Failed to decrement of initialize key " << key <<
" by offset " << offset
953 <<
" or initialize " << initial <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
956 MemcachedPrivate::setReturnType(returnType, rt);
970 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
977 const memcached_return_t rt = memcached_decrement_with_initial_by_key(mcd->d_ptr->memc,
978 groupKey.constData(),
987 const bool ok = memcached_success(rt);
989 qCWarning(C_MEMCACHED).nospace()
990 <<
"Failed to decrement or initialize key " << key <<
" in group " << groupKey
991 <<
" by offset " << offset <<
" or initial " << initial <<
": "
992 << memcached_strerror(mcd->d_ptr->memc, rt);
995 MemcachedPrivate::setReturnType(returnType, rt);
1001 const QByteArray &value,
1007 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1014 MemcachedPrivate::Flags flags;
1015 QByteArray _value = value;
1017 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
1018 flags |= MemcachedPrivate::Compressed;
1019 _value = qCompress(value, mcd->d_ptr->compressionLevel);
1022 const memcached_return_t rt = memcached_cas(mcd->d_ptr->memc,
1031 const bool ok = memcached_success(rt);
1033 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1034 qCWarning(C_MEMCACHED).nospace() <<
"Failed to compare and set (cas) key " << key <<
": "
1035 << memcached_strerror(mcd->d_ptr->memc, rt);
1038 MemcachedPrivate::setReturnType(returnType, rt);
1045 const QByteArray &value,
1051 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1058 MemcachedPrivate::Flags flags;
1059 QByteArray _value = value;
1061 if (mcd->d_ptr->compression && (_value.size() > mcd->d_ptr->compressionThreshold)) {
1062 flags |= MemcachedPrivate::Compressed;
1063 _value = qCompress(value, mcd->d_ptr->compressionLevel);
1066 const memcached_return_t rt = memcached_cas_by_key(mcd->d_ptr->memc,
1067 groupKey.constData(),
1077 const bool ok = memcached_success(rt);
1079 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
1080 qCWarning(C_MEMCACHED).nospace()
1081 <<
"Failed to compare and set (cas) key " << key <<
" in group " << groupKey <<
": "
1082 << memcached_strerror(mcd->d_ptr->memc, rt);
1085 MemcachedPrivate::setReturnType(returnType, rt);
1093 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1100 const memcached_return_t rt = memcached_flush_buffers(mcd->d_ptr->memc);
1102 const bool ok = memcached_success(rt);
1105 qCWarning(C_MEMCACHED) <<
"Failed to flush buffers:"
1106 << memcached_strerror(mcd->d_ptr->memc, rt);
1109 MemcachedPrivate::setReturnType(returnType, rt);
1117 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1124 const memcached_return_t rt = memcached_flush(mcd->d_ptr->memc, expiration);
1126 const bool ok = memcached_success(rt);
1129 qCWarning(C_MEMCACHED) <<
"Failed to wipe (flush) server content:"
1130 << memcached_strerror(mcd->d_ptr->memc, rt);
1133 MemcachedPrivate::setReturnType(returnType, rt);
1139 QHash<QByteArray, uint64_t> *casValues,
1142 QHash<QByteArray, QByteArray> ret;
1145 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1153 qCWarning(C_MEMCACHED) <<
"Can not get multiple values without a list of keys.";
1160 std::vector<const char *> _keys;
1161 _keys.reserve(keys.size());
1162 std::vector<size_t> _keysSizes;
1163 _keysSizes.reserve(keys.size());
1165 for (
const auto &key : keys) {
1166 _keys.push_back(key.data());
1167 _keysSizes.push_back(key.size());
1172 memcached_return_t rt =
1173 memcached_mget(mcd->d_ptr->memc, &_keys[0], &_keysSizes[0], _keys.size());
1175 if (memcached_success(rt)) {
1177 ret.reserve(keys.size());
1178 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1179 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
1181 const QByteArray rk =
1182 QByteArray(memcached_result_key_value(result),
1183 static_cast<qsizetype
>(memcached_result_key_length(result)));
1184 QByteArray rd(memcached_result_value(result),
1185 static_cast<qsizetype
>(memcached_result_length(result)));
1187 casValues->insert(rk, memcached_result_cas(result));
1189 const MemcachedPrivate::Flags flags{memcached_result_flags(result)};
1190 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1191 rd = qUncompress(rd);
1195 memcached_result_free(result);
1200 qCWarning(C_MEMCACHED) <<
"Failed to get values for multiple keys:"
1201 << memcached_strerror(mcd->d_ptr->memc, rt);
1204 MemcachedPrivate::setReturnType(returnType, rt);
1210 const QByteArrayList &keys,
1211 QHash<QByteArray, uint64_t> *casValues,
1214 QHash<QByteArray, QByteArray> ret;
1217 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1224 if (groupKey.isEmpty()) {
1225 qCWarning(C_MEMCACHED)
1226 <<
"Can not get multiple values from specific server when groupKey is empty.";
1234 qCWarning(C_MEMCACHED) <<
"Can not get multiple values without a list of keys.";
1241 std::vector<const char *> _keys;
1242 _keys.reserve(keys.size());
1243 std::vector<size_t> _keysSizes;
1244 _keysSizes.reserve(keys.size());
1246 for (
const auto &key : keys) {
1247 _keys.push_back(key.data());
1248 _keysSizes.push_back(key.size());
1253 memcached_return_t rt = memcached_mget_by_key(mcd->d_ptr->memc,
1254 groupKey.constData(),
1260 if (memcached_success(rt)) {
1262 ret.reserve(keys.size());
1263 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1264 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
1266 const QByteArray rk =
1267 QByteArray(memcached_result_key_value(result),
1268 static_cast<qsizetype
>(memcached_result_key_length(result)));
1269 QByteArray rd(memcached_result_value(result),
1270 static_cast<qsizetype
>(memcached_result_length(result)));
1272 casValues->insert(rk, memcached_result_cas(result));
1274 const MemcachedPrivate::Flags flags{memcached_result_flags(result)};
1275 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1276 rd = qUncompress(rd);
1280 memcached_result_free(result);
1285 qCWarning(C_MEMCACHED).nospace()
1286 <<
"Failed to get values for multiple keys in group " << groupKey <<
": "
1287 << memcached_strerror(mcd->d_ptr->memc, rt);
1290 MemcachedPrivate::setReturnType(returnType, rt);
1298 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1305 const memcached_return_t rt =
1306 memcached_touch(mcd->d_ptr->memc, key.constData(), key.size(), expiration);
1308 const bool ok = memcached_success(rt);
1311 qCWarning(C_MEMCACHED).nospace()
1312 <<
"Failed to touch key " << key <<
" with new expiration time " << expiration
1313 <<
" seconds: " << memcached_strerror(mcd->d_ptr->memc, rt);
1316 MemcachedPrivate::setReturnType(returnType, rt);
1327 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1334 const memcached_return_t rt = memcached_touch_by_key(mcd->d_ptr->memc,
1335 groupKey.constData(),
1341 const bool ok = memcached_success(rt);
1344 qCWarning(C_MEMCACHED).nospace()
1345 <<
"Failed to touch key " << key <<
" in group " << groupKey
1346 <<
" with new expiration time " << expiration
1347 <<
" seconds: " << memcached_strerror(mcd->d_ptr->memc, rt);
1350 MemcachedPrivate::setReturnType(returnType, rt);
1359 return c->
translate(
"Cutelyst::Memcached",
"The request was successfully executed.");
1361 return c->
translate(
"Cutelyst::Memcached",
1362 "An unknown failure has occurred in the Memcached server.");
1364 return c->
translate(
"Cutelyst::Memcached",
"A DNS failure has occurred.");
1367 "Cutelyst::Memcached",
1368 "An unknown error has occurred while trying to connect to a Memcached server.");
1370 return c->
translate(
"Cutelyst::Memcached",
1371 "An error has occurred while trying to write to a Memcached server.");
1373 return c->
translate(
"Cutelyst::Memcached",
1374 "An error has occurred while trying to read from a Memcached server.");
1377 "Cutelyst::Memcached",
1378 "An unknown error has occurred while trying to read from a Memcached server. This only "
1379 "occures when either there is a bug in the server, or in rare cases where an ethernet "
1380 "NIC is reporting dubious information.");
1382 return c->
translate(
"Cutelyst::Memcached",
1383 "An unknown error has occurred in the Memcached protocol.");
1385 return c->
translate(
"Cutelyst::Memcached",
1386 "An unknown Memcached client error has occurred internally.");
1388 return c->
translate(
"Cutelyst::Memcached",
1389 "An unknown error has occurred in the Memcached server.");
1391 return c->
translate(
"Cutelyst::Memcached",
"A general error occurred.");
1393 return c->
translate(
"Cutelyst::Memcached",
"The data for the given key alrey exists.");
1395 return c->
translate(
"Cutelyst::Memcached",
1396 "The data requested with the key given was not found.");
1398 return c->
translate(
"Cutelyst::Memcached",
"The request to store an object failed.");
1400 return c->
translate(
"Cutelyst::Memcached",
1401 "The requested object has been successfully stored on the server.");
1403 return c->
translate(
"Cutelyst::Memcached",
"The object requested was not found.");
1405 return c->
translate(
"Cutelyst::Memcached",
1406 "An error has occurred while trying to allocate memory.");
1408 return c->
translate(
"Cutelyst::Memcached",
1409 "The read operation was only partcially successful.");
1411 return c->
translate(
"Cutelyst::Memcached",
1412 "A multi request has been made, and some underterminate number of "
1413 "errors have occurred.");
1415 return c->
translate(
"Cutelyst::Memcached",
1416 "No servers have been added to the Memcached plugin.");
1419 "Cutelyst::Memcached",
1420 "The Memcached server has completed returning all of the objects requested.");
1422 return c->
translate(
"Cutelyst::Memcached",
1423 "The object requested by the key has been deleted.");
1425 return c->
translate(
"Cutelyst::Memcached",
1426 "A “stat” command has been returned in the protocol.");
1428 return c->
translate(
"Cutelyst::Memcached",
1429 "An error has occurred in the driver which has set errno.");
1431 return c->
translate(
"Cutelyst::Memcached",
1432 "The given method is not supported in the Memcached server.");
1434 return c->
translate(
"Cutelyst::Memcached",
1435 "A request has been made, but the Memcached server has not finished "
1436 "the fetch of the last request.");
1438 return c->
translate(
"Cutelyst::Memcached",
"The operation has timed out.");
1440 return c->
translate(
"Cutelyst::Memcached",
"The request has been buffered.");
1442 return c->
translate(
"Cutelyst::Memcached",
"The key provided is not a valid key.");
1445 "Cutelyst::Memcached",
1446 "The Memcached server you are connecting to has an invalid protocol. Most likely you "
1447 "are connecting to an older server that does not speak the binary protocol.");
1449 return c->
translate(
"Cutelyst::Memcached",
1450 "The requested Memcached server has been marked dead.");
1452 return c->
translate(
"Cutelyst::Memcached",
1453 "The Memcached server you are communicating with has a stat key which "
1454 "has not be defined in the protocol.");
1456 return c->
translate(
"Cutelyst::Memcached",
1457 "Item is too large for the Memcached server to store.");
1459 return c->
translate(
"Cutelyst::Memcached",
1460 "The arguments supplied to the given function were not valid.");
1463 "Cutelyst::Memcached",
1464 "The key that has been provided is too large for the given Memcached server.");
1466 return c->
translate(
"Cutelyst::Memcached",
1467 "An unknown issue has occurred during SASL authentication.");
1469 return c->
translate(
"Cutelyst::Memcached",
1470 "The credentials provided are not valid for this Memcached server.");
1472 return c->
translate(
"Cutelyst::Memcached",
"Authentication has been paused.");
1475 "Cutelyst::Memcached",
1476 "An error has occurred while trying to parse the configuration string.");
1478 return c->
translate(
"Cutelyst::Memcached",
1479 "An error has occurred in parsing the configuration string.");
1481 return c->
translate(
"Cutelyst::Memcached",
1482 "The method that was requested has been deprecated.");
1485 "Cutelyst::Memcached",
1486 "The Cutelyst Memcached plugin has not been registered to the application.");
1488 return c->
translate(
"Cutelyst::Memcached",
"An unknown error has occurred.");
1494 return QVersionNumber::fromString(QLatin1String(memcached_lib_version()));
1543 case MEMCACHED_IN_PROGRESS:
return Memcached::InProgress;
1544 case MEMCACHED_SERVER_TEMPORARILY_DISABLED:
return Memcached::ServerTemporaryDisabled;
1545 case MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE:
return Memcached::ServerMemoryAllocationFailure;
1546 case MEMCACHED_MAXIMUM_RETURN:
return Memcached::MaximumReturn;
1555 *rt1 = MemcachedPrivate::returnTypeConvert(rt2);
1559#include "moc_memcached.cpp"
The Cutelyst Application.
Engine * engine() const noexcept
void loadTranslations(const QString &filename, const QString &directory={}, const QString &prefix={}, const QString &suffix={})
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 QByteArray getByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
static bool increment(QByteArrayView key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool touchByKey(QByteArrayView groupKey, QByteArrayView key, time_t expiration, MemcachedReturnType *returnType=nullptr)
@ MemoryAllocationFailure
static QHash< QByteArray, QByteArray > mgetByKey(QByteArrayView groupKey, const QByteArrayList &keys, QHash< QByteArray, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
static const std::chrono::seconds expirationNotAddDuration
bool setup(Application *app) override
static bool decrement(QByteArrayView key, uint32_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool cas(QByteArrayView key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
static bool flush(time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool set(QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool flushBuffers(MemcachedReturnType *returnType=nullptr)
static bool incrementWithInitialByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool existByKey(QByteArrayView groupKey, QByteArrayView key, MemcachedReturnType *returnType=nullptr)
static bool remove(QByteArrayView key, MemcachedReturnType *returnType=nullptr)
static bool add(QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static const time_t expirationNotAdd
static QByteArray get(QByteArrayView key, uint64_t *cas=nullptr, MemcachedReturnType *returnType=nullptr)
static bool incrementByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool replace(QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool exist(QByteArrayView key, MemcachedReturnType *returnType=nullptr)
static bool casByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, uint64_t cas, MemcachedReturnType *returnType=nullptr)
static bool decrementWithInitialByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static QString errorString(Context *c, MemcachedReturnType rt)
static bool decrementWithInitial(QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool touch(QByteArrayView key, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool incrementWithInitial(QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
static bool removeByKey(QByteArrayView groupKey, QByteArrayView key, MemcachedReturnType *returnType=nullptr)
void setDefaultConfig(const QVariantMap &defaultConfig)
static bool addByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
Memcached(Application *parent)
static QVersionNumber libMemcachedVersion()
Returns the version of the currently used libmemcached.
static bool setByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static QHash< QByteArray, QByteArray > mget(const QByteArrayList &keys, QHash< QByteArray, uint64_t > *casValues=nullptr, MemcachedReturnType *returnType=nullptr)
static bool replaceByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, MemcachedReturnType *returnType=nullptr)
static bool decrementByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t *value=nullptr, MemcachedReturnType *returnType=nullptr)
The Cutelyst namespace holds all public Cutelyst API.