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)
21static thread_local Memcached *mcd =
nullptr;
24 static_cast<std::chrono::seconds::rep
>(MEMCACHED_EXPIRATION_NOT_ADD)};
28 , d_ptr(new MemcachedPrivate)
34 , d_ptr(new MemcachedPrivate(defaultConfig))
43 d->defaultConfig = defaultConfig;
50 d->loadedConfig = app->
engine()->
config(u
"Cutelyst_Memcached_Plugin"_s);
53 const QStringList serverList = d->config(u
"servers"_s).toString().split(u
';');
55 if (serverList.
empty()) {
59 for (
const QString &flag : {u
"verify_key"_s,
60 u
"remove_failed_servers"_s,
63 u
"hash_with_namespace"_s,
65 u
"randomize_replica_read"_s,
70 u
"tcp_keepalive"_s}) {
71 if (d->config(flag,
false).toBool()) {
77 const bool useUDP = d->config(u
"use_udp"_s,
false).toBool();
83 u
"number_of_replicas"_s,
86 u
"server_failure_limit"_s,
88 u
"socket_recv_size"_s,
89 u
"socket_send_size"_s,
91 u
"io_bytes_watermark"_s,
93 u
"io_msg_watermark"_s,
96 const QString _val = d->config(opt).toString();
107 qCInfo(C_MEMCACHED) <<
"Setting up connection to memcached servers using libmemcached"
108 << memcached_lib_version()
109 <<
"with the following configuration string:" << configString;
111 memcached_st *new_memc = memcached(configString.
constData(), configString.
size());
115 if (!serverList.
empty()) {
116 for (
const QString &server : serverList) {
119 uint16_t port = MemcachedPrivate::defaultPort;
121 bool isSocket =
false;
122 if (!serverParts.empty()) {
123 const auto part0 = serverParts.
at(0);
124 if (!part0.isEmpty()) {
125 name = part0.toString();
128 if (serverParts.size() > 1) {
129 const auto part1 = serverParts.at(1);
130 if (!part1.isEmpty()) {
132 weight = part1.toUInt();
134 port = part1.toUInt();
137 if (!isSocket && (serverParts.size() > 2)) {
138 const auto part2 = serverParts.at(2);
139 if (!part2.isEmpty()) {
140 weight = part2.toUInt();
146 memcached_return_t rc{MEMCACHED_FAILURE};
148 rc = memcached_server_add_unix_socket_with_weight(
150 if (Q_LIKELY(memcached_success(rc))) {
151 qCInfo(C_MEMCACHED) <<
"Added memcached server on socket" << name
152 <<
"with weight" << weight;
154 qCWarning(C_MEMCACHED).nospace()
155 <<
"Failed to add memcached server on socket " << name
156 <<
" with weight " << weight <<
": "
157 << memcached_strerror(new_memc, rc);
161 rc = memcached_server_add_udp_with_weight(
164 rc = memcached_server_add_with_weight(
167 if (Q_LIKELY(memcached_success(rc))) {
168 qCInfo(C_MEMCACHED).nospace().noquote()
169 <<
"Added memcached server on host " << name <<
":" << port
170 <<
" with weight" << weight;
172 qCWarning(C_MEMCACHED).nospace().noquote()
173 <<
"Failed to add memcached server no host " << name <<
":" << port
174 <<
" with weight " << weight <<
": "
175 << memcached_strerror(new_memc, rc);
181 if (Q_UNLIKELY(memcached_server_count(new_memc) == 0)) {
182 qCWarning(C_MEMCACHED)
183 <<
"Failed to add any memcached server. Adding default server on localhost"
185 memcached_return_t rc =
186 memcached_server_add(new_memc,
"localhost", MemcachedPrivate::defaultPort);
187 if (Q_UNLIKELY(!memcached_success(rc))) {
188 qCCritical(C_MEMCACHED)
189 <<
"Failed to add default memcached server. Memcached plugin will not"
190 <<
"work without a configured server!" << memcached_strerror(new_memc, rc);
191 memcached_free(new_memc);
197 d->compression = d->config(u
"compression"_s,
false).toBool();
198 d->compressionLevel = d->config(u
"compression_level"_s, -1).toInt();
199 d->compressionThreshold =
200 d->config(u
"compression_threshold"_s, 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 = d->config(u
"encryption_key"_s).toString();
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 = d->config(u
"sasl_user"_s).toString();
228 const QString saslPass = d->config(u
"sasl_password"_s).toString();
230 const memcached_return_t rt = memcached_set_sasl_auth_data(
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)";
267 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
271 MemcachedPrivate::Flags flags;
272 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
274 const memcached_return_t rt = memcached_set(mcd->d_ptr->memc,
282 const bool ok = memcached_success(rt);
285 qCWarning(C_MEMCACHED).nospace()
286 <<
"Failed to store key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
289 MemcachedPrivate::setReturnType(returnType, rt);
300 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
304 MemcachedPrivate::Flags flags;
305 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
307 const memcached_return_t rt = memcached_set_by_key(mcd->d_ptr->memc,
317 const bool ok = memcached_success(rt);
320 qCWarning(C_MEMCACHED).nospace()
321 <<
"Failed to store key " << key <<
" on group " << groupKey <<
": "
322 << memcached_strerror(mcd->d_ptr->memc, rt);
325 MemcachedPrivate::setReturnType(returnType, rt);
335 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
339 MemcachedPrivate::Flags flags;
340 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
342 const memcached_return_t rt = memcached_add(mcd->d_ptr->memc,
350 const bool ok = memcached_success(rt);
352 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
353 qCWarning(C_MEMCACHED).nospace()
354 <<
"Failed to add key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
357 MemcachedPrivate::setReturnType(returnType, rt);
368 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
372 MemcachedPrivate::Flags flags;
373 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
375 const memcached_return_t rt = memcached_add_by_key(mcd->d_ptr->memc,
385 const bool ok = memcached_success(rt);
387 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
388 qCWarning(C_MEMCACHED).nospace() <<
"Failed to add key " << key <<
" on group " << groupKey
389 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
392 MemcachedPrivate::setReturnType(returnType, rt);
402 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
406 MemcachedPrivate::Flags flags;
407 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
409 const memcached_return_t rt = memcached_replace(mcd->d_ptr->memc,
417 const bool ok = memcached_success(rt);
419 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
420 qCWarning(C_MEMCACHED).nospace()
421 <<
"Failed to replace key " << key <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
424 MemcachedPrivate::setReturnType(returnType, rt);
435 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
439 MemcachedPrivate::Flags flags;
440 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
442 const memcached_return_t rt = memcached_replace_by_key(mcd->d_ptr->memc,
452 const bool ok = memcached_success(rt);
454 if (!ok && (rt != MEMCACHED_NOTSTORED)) {
455 qCWarning(C_MEMCACHED).nospace()
456 <<
"Failed to replace key " << key <<
" on group " << groupKey <<
": "
457 << memcached_strerror(mcd->d_ptr->memc, rt);
460 MemcachedPrivate::setReturnType(returnType, rt);
469 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
473 memcached_return_t rt{MEMCACHED_FAILURE};
476 std::vector<const char *> keys;
477 std::vector<size_t> sizes;
479 sizes.emplace_back(key.
size());
480 rt = memcached_mget(mcd->d_ptr->memc, &keys[0], &sizes[0], keys.size());
482 if (memcached_success(rt)) {
483 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
487 static_cast<QByteArray::size_type
>(memcached_result_length(result)));
489 *
cas = memcached_result_cas(result);
491 retData = MemcachedPrivate::uncompressIfNeeded(retData, result);
495 memcached_fetch_result(mcd->d_ptr->memc,
nullptr,
nullptr);
497 memcached_result_free(result);
500 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
501 qCWarning(C_MEMCACHED).nospace() <<
"Failed to get data for key " << key <<
": "
502 << memcached_strerror(mcd->d_ptr->memc, rt);
505 MemcachedPrivate::setReturnType(returnType, rt);
517 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
523 std::vector<const char *> keys;
524 std::vector<size_t> sizes;
526 sizes.emplace_back(key.
size());
527 memcached_return_t rt = memcached_mget_by_key(
528 mcd->d_ptr->memc, groupKey.
constData(), groupKey.
size(), &keys[0], &sizes[0], keys.size());
530 if (memcached_success(rt)) {
531 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
535 static_cast<QByteArray::size_type
>(memcached_result_length(result)));
537 *
cas = memcached_result_cas(result);
539 retData = MemcachedPrivate::uncompressIfNeeded(retData, result);
543 memcached_fetch_result(mcd->d_ptr->memc,
nullptr,
nullptr);
545 memcached_result_free(result);
548 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
549 qCWarning(C_MEMCACHED).nospace()
550 <<
"Failed to get data for key " << key <<
" on group " << groupKey <<
": "
551 << memcached_strerror(mcd->d_ptr->memc, rt);
554 MemcachedPrivate::setReturnType(returnType, rt);
561 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
565 const memcached_return_t rt =
566 memcached_delete(mcd->d_ptr->memc, key.
constData(), key.
size(), 0);
568 const bool ok = memcached_success(rt);
570 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
571 qCWarning(C_MEMCACHED).nospace() <<
"Failed to remove data for key " << key <<
": "
572 << memcached_strerror(mcd->d_ptr->memc, rt);
575 MemcachedPrivate::setReturnType(returnType, rt);
582 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
586 const memcached_return_t rt = memcached_delete_by_key(
589 const bool ok = memcached_success(rt);
591 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
592 qCWarning(C_MEMCACHED).nospace()
593 <<
"Failed to remove data for key " << key <<
" on group " << groupKey <<
": "
594 << memcached_strerror(mcd->d_ptr->memc, rt);
597 MemcachedPrivate::setReturnType(returnType, rt);
604 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
608 const memcached_return_t rt = memcached_exist(mcd->d_ptr->memc, key.
constData(), key.
size());
610 const bool ok = memcached_success(rt);
612 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
613 qCWarning(C_MEMCACHED).nospace() <<
"Failed to check existence of key " << key <<
": "
614 << memcached_strerror(mcd->d_ptr->memc, rt);
617 MemcachedPrivate::setReturnType(returnType, rt);
624 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
628 const memcached_return_t rt = memcached_exist_by_key(
631 const bool ok = memcached_success(rt);
633 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
634 qCWarning(C_MEMCACHED).nospace()
635 <<
"Failed to check existence of key " << key <<
" in group " << groupKey <<
": "
636 << memcached_strerror(mcd->d_ptr->memc, rt);
639 MemcachedPrivate::setReturnType(returnType, rt);
649 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
653 const memcached_return_t rt =
654 memcached_increment(mcd->d_ptr->memc, key.
constData(), key.
size(), offset, value);
656 const bool ok = memcached_success(rt);
658 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
659 qCWarning(C_MEMCACHED).nospace() <<
"Failed to increment key " << key <<
" by " << offset
660 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
663 MemcachedPrivate::setReturnType(returnType, rt);
674 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
678 const memcached_return_t rt = memcached_increment_by_key(mcd->d_ptr->memc,
686 const bool ok = memcached_success(rt);
688 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
689 qCWarning(C_MEMCACHED).nospace()
690 <<
"Failed to increment key " << key <<
" in group " << groupKey <<
" by " << offset
691 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
694 MemcachedPrivate::setReturnType(returnType, rt);
706 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
710 const memcached_return_t rt = memcached_increment_with_initial(
711 mcd->d_ptr->memc, key.
constData(), key.
size(), offset, initial, expiration, value);
713 const bool ok = memcached_success(rt);
716 qCWarning(C_MEMCACHED).nospace()
717 <<
"Failed to increment or initialize key " << key <<
" by offset " << offset
718 <<
" or initial " << initial <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
721 MemcachedPrivate::setReturnType(returnType, rt);
734 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
738 const memcached_return_t rt = memcached_increment_with_initial_by_key(mcd->d_ptr->memc,
748 const bool ok = memcached_success(rt);
750 qCWarning(C_MEMCACHED).nospace()
751 <<
"Failed to increment or initializes key " << key <<
" in group " << groupKey
752 <<
" by offset " << offset <<
" or initial " << initial <<
": "
753 << memcached_strerror(mcd->d_ptr->memc, rt);
756 MemcachedPrivate::setReturnType(returnType, rt);
766 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
770 const memcached_return_t rt =
771 memcached_decrement(mcd->d_ptr->memc, key.
constData(), key.
size(), offset, value);
773 const bool ok = memcached_success(rt);
775 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
776 qCWarning(C_MEMCACHED).nospace() <<
"Failed to decrement key " << key <<
" by " << offset
777 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
780 MemcachedPrivate::setReturnType(returnType, rt);
791 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
795 const memcached_return_t rt = memcached_decrement_by_key(mcd->d_ptr->memc,
803 const bool ok = memcached_success(rt);
805 if (!ok && (rt != MEMCACHED_NOTFOUND)) {
806 qCWarning(C_MEMCACHED).nospace()
807 <<
"Failed to decrement key " << key <<
" in group " << groupKey <<
" by " << offset
808 <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
811 MemcachedPrivate::setReturnType(returnType, rt);
823 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
827 const memcached_return_t rt = memcached_decrement_with_initial(
828 mcd->d_ptr->memc, key.
constData(), key.
size(), offset, initial, expiration, value);
830 const bool ok = memcached_success(rt);
833 qCWarning(C_MEMCACHED).nospace()
834 <<
"Failed to decrement of initialize key " << key <<
" by offset " << offset
835 <<
" or initialize " << initial <<
": " << memcached_strerror(mcd->d_ptr->memc, rt);
838 MemcachedPrivate::setReturnType(returnType, rt);
851 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
855 const memcached_return_t rt = memcached_decrement_with_initial_by_key(mcd->d_ptr->memc,
865 const bool ok = memcached_success(rt);
867 qCWarning(C_MEMCACHED).nospace()
868 <<
"Failed to decrement or initialize key " << key <<
" in group " << groupKey
869 <<
" by offset " << offset <<
" or initial " << initial <<
": "
870 << memcached_strerror(mcd->d_ptr->memc, rt);
873 MemcachedPrivate::setReturnType(returnType, rt);
884 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
888 MemcachedPrivate::Flags flags;
889 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
891 const memcached_return_t rt = memcached_cas(mcd->d_ptr->memc,
900 const bool ok = memcached_success(rt);
902 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
903 qCWarning(C_MEMCACHED).nospace() <<
"Failed to compare and set (cas) key " << key <<
": "
904 << memcached_strerror(mcd->d_ptr->memc, rt);
907 MemcachedPrivate::setReturnType(returnType, rt);
919 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
923 MemcachedPrivate::Flags flags;
924 const QByteArray _value = MemcachedPrivate::compressIfNeeded(value, flags);
926 const memcached_return_t rt = memcached_cas_by_key(mcd->d_ptr->memc,
937 const bool ok = memcached_success(rt);
939 if (!ok && (rt != MEMCACHED_DATA_EXISTS)) {
940 qCWarning(C_MEMCACHED).nospace()
941 <<
"Failed to compare and set (cas) key " << key <<
" in group " << groupKey <<
": "
942 << memcached_strerror(mcd->d_ptr->memc, rt);
945 MemcachedPrivate::setReturnType(returnType, rt);
952 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
956 const memcached_return_t rt = memcached_flush_buffers(mcd->d_ptr->memc);
958 const bool ok = memcached_success(rt);
961 qCWarning(C_MEMCACHED) <<
"Failed to flush buffers:"
962 << memcached_strerror(mcd->d_ptr->memc, rt);
965 MemcachedPrivate::setReturnType(returnType, rt);
972 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
976 const memcached_return_t rt = memcached_flush(mcd->d_ptr->memc, expiration);
978 const bool ok = memcached_success(rt);
981 qCWarning(C_MEMCACHED) <<
"Failed to wipe (flush) server content:"
982 << memcached_strerror(mcd->d_ptr->memc, rt);
985 MemcachedPrivate::setReturnType(returnType, rt);
996 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
1001 qCWarning(C_MEMCACHED) <<
"Can not get multiple values without a list of keys.";
1008 std::vector<const char *> _keys;
1010 std::vector<size_t> _keysSizes;
1011 _keysSizes.reserve(keys.
size());
1013 for (
const auto &key : keys) {
1014 _keys.emplace_back(key.data());
1015 _keysSizes.emplace_back(key.size());
1020 memcached_return_t rt =
1021 memcached_mget(mcd->d_ptr->memc, &_keys[0], &_keysSizes[0], _keys.size());
1023 if (memcached_success(rt)) {
1026 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1027 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
1030 QByteArray(memcached_result_key_value(result),
1031 static_cast<qsizetype
>(memcached_result_key_length(result)));
1032 QByteArray rd(memcached_result_value(result),
1033 static_cast<qsizetype
>(memcached_result_length(result)));
1035 casValues->
insert(rk, memcached_result_cas(result));
1037 rd = MemcachedPrivate::uncompressIfNeeded(rd, result);
1040 memcached_result_free(result);
1045 qCWarning(C_MEMCACHED) <<
"Failed to get values for multiple keys:"
1046 << memcached_strerror(mcd->d_ptr->memc, rt);
1049 MemcachedPrivate::setReturnType(returnType, rt);
1061 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
1066 qCWarning(C_MEMCACHED)
1067 <<
"Can not get multiple values from specific server when groupKey is empty.";
1075 qCWarning(C_MEMCACHED) <<
"Can not get multiple values without a list of keys.";
1082 std::vector<const char *> _keys;
1084 std::vector<size_t> _keysSizes;
1085 _keysSizes.reserve(keys.
size());
1087 for (
const auto &key : keys) {
1088 _keys.emplace_back(key.data());
1089 _keysSizes.emplace_back(key.size());
1094 memcached_return_t rt = memcached_mget_by_key(mcd->d_ptr->memc,
1101 if (memcached_success(rt)) {
1104 while ((rt != MEMCACHED_END) && (rt != MEMCACHED_NOTFOUND)) {
1105 memcached_result_st *result = memcached_fetch_result(mcd->d_ptr->memc,
nullptr, &rt);
1108 QByteArray(memcached_result_key_value(result),
1109 static_cast<qsizetype
>(memcached_result_key_length(result)));
1110 QByteArray rd(memcached_result_value(result),
1111 static_cast<qsizetype
>(memcached_result_length(result)));
1113 casValues->
insert(rk, memcached_result_cas(result));
1115 rd = MemcachedPrivate::uncompressIfNeeded(rd, result);
1118 memcached_result_free(result);
1123 qCWarning(C_MEMCACHED).nospace()
1124 <<
"Failed to get values for multiple keys in group " << groupKey <<
": "
1125 << memcached_strerror(mcd->d_ptr->memc, rt);
1128 MemcachedPrivate::setReturnType(returnType, rt);
1135 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
1139 const memcached_return_t rt =
1140 memcached_touch(mcd->d_ptr->memc, key.
constData(), key.
size(), expiration);
1142 const bool ok = memcached_success(rt);
1145 qCWarning(C_MEMCACHED).nospace()
1146 <<
"Failed to touch key " << key <<
" with new expiration time " << expiration
1147 <<
" seconds: " << memcached_strerror(mcd->d_ptr->memc, rt);
1150 MemcachedPrivate::setReturnType(returnType, rt);
1160 if (!MemcachedPrivate::isRegistered(mcd, returnType)) {
1164 const memcached_return_t rt = memcached_touch_by_key(mcd->d_ptr->memc,
1171 const bool ok = memcached_success(rt);
1174 qCWarning(C_MEMCACHED).nospace()
1175 <<
"Failed to touch key " << key <<
" in group " << groupKey
1176 <<
" with new expiration time " << expiration
1177 <<
" seconds: " << memcached_strerror(mcd->d_ptr->memc, rt);
1180 MemcachedPrivate::setReturnType(returnType, rt);
1191 return c->
qtTrId(
"cutelyst-memc-rt-success");
1194 return c->
qtTrId(
"cutelyst-memc-rt-failure");
1197 return c->
qtTrId(
"cutelyst-memc-rt-hostlookupfailure");
1200 return c->
qtTrId(
"cutelyst-memc-rt-connectionfailure");
1203 return c->
qtTrId(
"cutelyst-memc-rt-writefailure");
1206 return c->
qtTrId(
"cutelyst-memc-rt-readfailure");
1211 return c->
qtTrId(
"cutelyst-memc-rt-unknownreadfailure");
1214 return c->
qtTrId(
"cutelyst-memc-rt-protocolerror");
1217 return c->
qtTrId(
"cutelyst-memc-rt-clienterror");
1220 return c->
qtTrId(
"cutelyst-memc-rt-servererror");
1223 return c->
qtTrId(
"cutelyst-memc-rt-error");
1226 return c->
qtTrId(
"cutelyst-memc-rt-dataexists");
1229 return c->
qtTrId(
"cutelyst-memc-rt-datadoesnotexist");
1232 return c->
qtTrId(
"cutelyst-memc-rt-notstored");
1235 return c->
qtTrId(
"cutelyst-memc-rt-stored");
1238 return c->
qtTrId(
"cutelyst-memc-notfound");
1241 return c->
qtTrId(
"cutelyst-memc-rt-memallocfailure");
1244 return c->
qtTrId(
"cutelyst-memc-rt-partread");
1248 return c->
qtTrId(
"cutelyst-memc-rt-someerrors");
1251 return c->
qtTrId(
"cutelyst-memc-rt-noservers");
1254 return c->
qtTrId(
"cutelyst-memc-rt-end");
1257 return c->
qtTrId(
"cutelyst-memc-rt-deleted");
1260 return c->
qtTrId(
"cutelyst-memc-rt-stat");
1263 return qtTrId(
"cutelyst-memc-rt-errno");
1266 return c->
qtTrId(
"cutelyst-memc-rt-notsupported");
1270 return c->
qtTrId(
"cutelyst-memc-rt-fetchnotfinished");
1273 return c->
qtTrId(
"cutelyst-memc-rt-timeout");
1276 return c->
qtTrId(
"cutelyst-memc-rt-buffered");
1279 return c->
qtTrId(
"cutelyst-memc-rt-badkeyprov");
1283 return c->
qtTrId(
"cutelyst-memc-rt-invalidhostprot");
1286 return c->
qtTrId(
"cutelyst-memc-rt-servermarkeddead");
1290 return c->
qtTrId(
"cutelyst-memc-rt-unknownstatkey");
1293 return c->
qtTrId(
"cutelyst-memc-rt-e2big");
1296 return c->
qtTrId(
"cutelyst-memc-rt-invalidarg");
1299 return c->
qtTrId(
"cutelyst-memc-rt-key2big");
1302 return c->
qtTrId(
"cutelyst-memc-rt-authproblem");
1305 return c->
qtTrId(
"cutelyst-memc-rt-authfailure");
1308 return c->
qtTrId(
"cutelyst-memc-rt-authcont");
1311 return c->
qtTrId(
"cutelyst-memc-rt-parseerr");
1314 return c->
qtTrId(
"cutelyst-memc-rt-parseusererr");
1317 return c->
qtTrId(
"cutelyst-memc-rt-deprecated");
1320 return c->
qtTrId(
"cutelyst-memc-rt-pluginnotregistered");
1323 return c->
qtTrId(
"cutelyst-memc-rt-unknown-err");
1341 case MEMCACHED_SUCCESS:
return Success;
1342 case MEMCACHED_FAILURE:
return Failure;
1343 case MEMCACHED_HOST_LOOKUP_FAILURE:
return HostLookupFailure;
1344 case MEMCACHED_CONNECTION_FAILURE:
return ConnectionFailure;
1345 case MEMCACHED_CONNECTION_BIND_FAILURE:
return HostLookupFailure;
1346 case MEMCACHED_WRITE_FAILURE:
return WriteFailure;
1347 case MEMCACHED_READ_FAILURE:
return ReadFailure;
1348 case MEMCACHED_UNKNOWN_READ_FAILURE:
return UnknownReadFailure;
1349 case MEMCACHED_PROTOCOL_ERROR:
return ProtocolError;
1350 case MEMCACHED_CLIENT_ERROR:
return ClientError;
1351 case MEMCACHED_SERVER_ERROR:
return ServerError;
1352 case MEMCACHED_ERROR:
return Error;
1353 case MEMCACHED_DATA_EXISTS:
return DataExists;
1354 case MEMCACHED_DATA_DOES_NOT_EXIST:
return DataDoesNotExist;
1355 case MEMCACHED_NOTSTORED:
return NotStored;
1356 case MEMCACHED_STORED:
return Stored;
1357 case MEMCACHED_NOTFOUND:
return NotFound;
1358 case MEMCACHED_MEMORY_ALLOCATION_FAILURE:
return MemoryAllocationFailure;
1359 case MEMCACHED_PARTIAL_READ:
return PartialRead;
1360 case MEMCACHED_SOME_ERRORS:
return SomeErrors;
1361 case MEMCACHED_NO_SERVERS:
return NoServers;
1362 case MEMCACHED_END:
return End;
1363 case MEMCACHED_DELETED:
return Deleted;
1364 case MEMCACHED_STAT:
return Stat;
1365 case MEMCACHED_ERRNO:
return Errno;
1366 case MEMCACHED_NOT_SUPPORTED:
return NotSupported;
1367 case MEMCACHED_FETCH_NOTFINISHED:
return FetchNotFinished;
1368 case MEMCACHED_TIMEOUT:
return Timeout;
1369 case MEMCACHED_BUFFERED:
return Buffered;
1370 case MEMCACHED_BAD_KEY_PROVIDED:
return BadKeyProvided;
1371 case MEMCACHED_INVALID_HOST_PROTOCOL:
return InvalidHostProtocol;
1372 case MEMCACHED_SERVER_MARKED_DEAD:
return ServerMarkedDead;
1373 case MEMCACHED_UNKNOWN_STAT_KEY:
return UnknownStatKey;
1374 case MEMCACHED_E2BIG:
return E2Big;
1375 case MEMCACHED_INVALID_ARGUMENTS:
return InvalidArguments;
1376 case MEMCACHED_KEY_TOO_BIG:
return KeyTooBig;
1377 case MEMCACHED_AUTH_PROBLEM:
return AuthProblem;
1378 case MEMCACHED_AUTH_FAILURE:
return AuthFailure;
1379 case MEMCACHED_AUTH_CONTINUE:
return AuthContinue;
1380 case MEMCACHED_PARSE_ERROR:
return ParseError;
1381 case MEMCACHED_PARSE_USER_ERROR:
return ParseUserError;
1382 case MEMCACHED_DEPRECATED:
return Deprecated;
1383 case MEMCACHED_IN_PROGRESS:
return InProgress;
1384 case MEMCACHED_SERVER_TEMPORARILY_DISABLED:
return ServerTemporaryDisabled;
1385 case MEMCACHED_SERVER_MEMORY_ALLOCATION_FAILURE:
return ServerMemoryAllocationFailure;
1386 case MEMCACHED_MAXIMUM_RETURN:
return MaximumReturn;
1387 default:
return Success;
1400 *rt1 = MemcachedPrivate::returnTypeConvert(rt2);
1412 qCCritical(C_MEMCACHED) <<
"Memcached plugin not registered";
1428 if (mcd->d_ptr->compression && (value.size() > mcd->d_ptr->compressionThreshold)) {
1429 flags |= MemcachedPrivate::Compressed;
1430 return qCompress(value, mcd->d_ptr->compressionLevel);
1442 memcached_result_st *result)
1444 const MemcachedPrivate::Flags flags{memcached_result_flags(result)};
1445 if (flags.testFlag(MemcachedPrivate::Compressed)) {
1446 return qUncompress(value);
1461 return loadedConfig.
value(key, defaultConfig.value(key, defaultValue));
1464#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 qtTrId(const char *id, int n=-1) const
QVariantMap config(const QString &entity) const
Cutelyst Memcached plugin.
static bool exist(QByteArrayView key, ReturnType *returnType=nullptr)
static bool touch(QByteArrayView key, time_t expiration, ReturnType *returnType=nullptr)
static bool flush(time_t expiration, ReturnType *returnType=nullptr)
static bool touchByKey(QByteArrayView groupKey, QByteArrayView key, time_t expiration, ReturnType *returnType=nullptr)
static bool incrementByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool flushBuffers(ReturnType *returnType=nullptr)
static const std::chrono::seconds expirationNotAddDuration
bool setup(Application *app) override
static bool decrementWithInitial(QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool removeByKey(QByteArrayView groupKey, QByteArrayView key, ReturnType *returnType=nullptr)
static bool incrementWithInitial(QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static QHash< QByteArray, QByteArray > mgetByKey(QByteArrayView groupKey, const QByteArrayList &keys, QHash< QByteArray, uint64_t > *casValues=nullptr, ReturnType *returnType=nullptr)
static bool cas(QByteArrayView key, const QByteArray &value, time_t expiration, uint64_t cas, ReturnType *returnType=nullptr)
static bool replace(QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
static bool set(QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
static bool decrement(QByteArrayView key, uint32_t offset, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool replaceByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
static bool decrementByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool casByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, uint64_t cas, ReturnType *returnType=nullptr)
static QString errorString(Context *c, ReturnType rt)
static QHash< QByteArray, QByteArray > mget(const QByteArrayList &keys, QHash< QByteArray, uint64_t > *casValues=nullptr, ReturnType *returnType=nullptr)
static bool decrementWithInitialByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static QByteArray getByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t *cas=nullptr, ReturnType *returnType=nullptr)
static const time_t expirationNotAdd
static bool addByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
static bool incrementWithInitialByKey(QByteArrayView groupKey, QByteArrayView key, uint64_t offset, uint64_t initial, time_t expiration, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool increment(QByteArrayView key, uint32_t offset, uint64_t *value=nullptr, ReturnType *returnType=nullptr)
static bool setByKey(QByteArrayView groupKey, QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
void setDefaultConfig(const QVariantMap &defaultConfig)
static QByteArray get(QByteArrayView key, uint64_t *cas=nullptr, ReturnType *returnType=nullptr)
static bool existByKey(QByteArrayView groupKey, QByteArrayView key, ReturnType *returnType=nullptr)
Memcached(Application *parent)
static QVersionNumber libMemcachedVersion()
Returns the version of the currently used libmemcached.
static bool remove(QByteArrayView key, ReturnType *returnType=nullptr)
@ MemoryAllocationFailure
static bool add(QByteArrayView key, const QByteArray &value, time_t expiration, ReturnType *returnType=nullptr)
Base class for Cutelyst Plugins.
The Cutelyst namespace holds all public Cutelyst API.
const char * constData() const const
qsizetype size() const const
QByteArrayView::const_pointer constData() const const
bool isEmpty() const const
qsizetype size() const const
QHash::iterator insert(const Key &key, const T &value)
void reserve(qsizetype size)
QList::reference emplaceBack(Args &&... args)
qsizetype size() const const
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
const QChar at(qsizetype position) const const
bool isEmpty() const const
QString & replace(QChar before, QChar after, Qt::CaseSensitivity cs)
bool startsWith(QChar c, Qt::CaseSensitivity cs) const const
QString toUpper() const const
QByteArray toUtf8() const const
QString join(QChar separator) const const
QList< QStringView > split(QChar sep, Qt::SplitBehavior behavior, Qt::CaseSensitivity cs) const const
QVersionNumber fromString(QAnyStringView string, qsizetype *suffixIndex)