2 +--------------------------------------------------------------------+
3 | libmemcached - C/C++ Client Library for memcached |
4 +--------------------------------------------------------------------+
5 | Redistribution and use in source and binary forms, with or without |
6 | modification, are permitted under the terms of the BSD license. |
7 | You should have received a copy of the license in a bundled file |
8 | named LICENSE; in case you did not receive a copy you can review |
9 | the terms online at: https://opensource.org/licenses/BSD-3-Clause |
10 +--------------------------------------------------------------------+
11 | Copyright (c) 2006-2014 Brian Aker https://datadifferential.com/ |
12 | Copyright (c) 2020 Michael Wallner <mike@php.net> |
13 +--------------------------------------------------------------------+
16 #include "libmemcached/common.h"
19 memcached_return_t
send_quit_message(memcached_instance_st
*instance
) {
20 memcached_return_t rc
;
21 if (instance
->root
->flags
.binary_protocol
) {
22 protocol_binary_request_quit request
= {}; // = {.bytes= {0}};
24 initialize_binary_request(instance
, request
.message
.header
);
26 request
.message
.header
.request
.opcode
= PROTOCOL_BINARY_CMD_QUIT
;
27 request
.message
.header
.request
.datatype
= PROTOCOL_BINARY_RAW_BYTES
;
29 libmemcached_io_vector_st vector
[] = {{request
.bytes
, sizeof(request
.bytes
)}};
31 rc
= memcached_vdo(instance
, vector
, 1, true);
33 libmemcached_io_vector_st vector
[] = {{memcached_literal_param("quit\r\n")}};
35 rc
= memcached_vdo(instance
, vector
, 1, true);
41 void drain_instance(memcached_instance_st
*instance
) {
42 /* read until socket is closed, or there is an error
43 * closing the socket before all data is read
44 * results in server throwing away all data which is
47 * In .40 we began to only do this if we had been doing buffered
48 * requests of had replication enabled.
50 if (instance
->root
->flags
.buffer_requests
or instance
->root
->number_of_replicas
) {
51 memcached_io_slurp(instance
);
55 * memcached_io_read may call memcached_quit_server with io_death if
56 * it encounters problems, but we don't care about those occurences.
57 * The intention of that loop is to drain the data sent from the
58 * server to ensure that the server processed all of the data we
61 instance
->server_failure_counter
= 0;
62 instance
->server_timeout_counter
= 0;
67 This closes all connections (forces flush of input as well).
69 Maybe add a host specific, or key specific version?
71 The reason we send "quit" is that in case we have buffered IO, this
72 will force data to be completed.
75 void memcached_quit_server(memcached_instance_st
*instance
, bool io_death
) {
76 if (instance
->valid()) {
77 if (io_death
== false and memcached_is_udp(instance
->root
) == false
78 and instance
->is_shutting_down() == false)
80 send_quit_message(instance
);
82 instance
->start_close_socket();
83 drain_instance(instance
);
87 instance
->close_socket();
89 if (io_death
and memcached_is_udp(instance
->root
)) {
91 If using UDP, we should stop using the server briefly on every IO
92 failure. If using TCP, it may be that the connection went down a
93 short while ago (e.g. the server failed) and we've only just
94 noticed, so we should only set the retry timeout on a connect
95 failure (which doesn't call this method).
97 memcached_mark_server_for_timeout(instance
);
101 void send_quit(Memcached
*memc
) {
102 for (uint32_t x
= 0; x
< memcached_server_count(memc
); x
++) {
103 memcached_instance_st
*instance
= memcached_instance_fetch(memc
, x
);
105 memcached_quit_server(instance
, false);
109 void memcached_quit(memcached_st
*shell
) {
110 Memcached
*memc
= memcached2Memcached(shell
);
111 memcached_return_t rc
;
112 if (memcached_failed(rc
= initialize_query(memc
, true))) {