1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18
19#ifndef BRPC_PROGRESSIVE_ATTACHMENT_H
20#define BRPC_PROGRESSIVE_ATTACHMENT_H
21
22#include "brpc/callback.h"
23#include "butil/atomicops.h"
24#include "butil/iobuf.h"
25#include "butil/endpoint.h" // butil::EndPoint
26#include "bthread/types.h" // bthread_id_t
27#include "brpc/socket_id.h" // SocketUniquePtr
28#include "brpc/shared_object.h" // SharedObject
29
30namespace brpc {
31
32class ProgressiveAttachment : public SharedObject {
33friend class Controller;
34public:
35 // [Thread-safe]
36 // Write `data' as one HTTP chunk to peer ASAP.
37 // Returns 0 on success, -1 otherwise and errno is set.
38 // Errnos are same as what Socket.Write may set.
39 int Write(const butil::IOBuf& data);
40 int Write(const void* data, size_t n);
41
42 // Get ip/port of peer/self.
43 butil::EndPoint remote_side() const;
44 butil::EndPoint local_side() const;
45
46 // [Not thread-safe and can only be called once]
47 // Run the callback when the underlying connection is broken (thus
48 // transmission of the attachment is permanently stopped), or when
49 // this attachment is destructed. In another word, the callback will
50 // always be run.
51 void NotifyOnStopped(google::protobuf::Closure* callback);
52
53protected:
54 // Transfer-Encoding is added since HTTP/1.1. If the protocol of the
55 // response is before_http_1_1, we will write the data directly to the
56 // socket without any futher modification and close the socket after all the
57 // data has been written (so the client would receive EOF). Otherwise we
58 // will encode each piece of data in the format of chunked-encoding.
59 ProgressiveAttachment(SocketUniquePtr& movable_httpsock,
60 bool before_http_1_1);
61 ~ProgressiveAttachment();
62
63 // Called by controller only.
64 void MarkRPCAsDone(bool rpc_failed);
65
66 bool _before_http_1_1;
67 bool _pause_from_mark_rpc_as_done;
68 butil::atomic<int> _rpc_state;
69 butil::Mutex _mutex;
70 SocketUniquePtr _httpsock;
71 butil::IOBuf _saved_buf;
72 bthread_id_t _notify_id;
73
74private:
75 static const int RPC_RUNNING;
76 static const int RPC_SUCCEED;
77 static const int RPC_FAILED;
78};
79
80} // namespace brpc
81
82
83#endif // BRPC_PROGRESSIVE_ATTACHMENT_H
84