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 | |
30 | namespace brpc { |
31 | |
32 | class ProgressiveAttachment : public SharedObject { |
33 | friend class Controller; |
34 | public: |
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 | |
53 | protected: |
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 | |
74 | private: |
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 | |