Branch data Line data Source code
1 : : /*
2 : : * Copyright 2025 Jinwoo Sung
3 : : *
4 : : * Licensed under the Apache License, Version 2.0 (the "License");
5 : : * you may not use this file except in compliance with the License.
6 : : * You may obtain a copy of the License at
7 : : *
8 : : * http://www.apache.org/licenses/LICENSE-2.0
9 : : *
10 : : * Unless required by applicable law or agreed to in writing, software
11 : : * distributed under the License is distributed on an "AS IS" BASIS,
12 : : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 : : * See the License for the specific language governing permissions and
14 : : * limitations under the License.
15 : : */
16 : :
17 : : #pragma once
18 : :
19 : : #include <optional>
20 : : #include <variant>
21 : :
22 : : #include "wirestead/interface/result_channel.hpp"
23 : :
24 : : namespace wirestead::interface {
25 : :
26 : : /**
27 : : * A single connection pinned for one Reliable send, including capacity retries.
28 : : *
29 : : * All methods return promptly and serialize with connection replacement, stop
30 : : * and admission. No method invokes a Channel/user callback inline.
31 : : * The handle keeps its connection record alive after reconnect; it must never
32 : : * redirect a write to a replacement connection.
33 : : */
34 : : class WIRESTEAD_API WriteConnection {
35 : : public:
36 : 1067 : virtual ~WriteConnection() = default;
37 : :
38 : : /**
39 : : * nullopt: capacity is still blocked; acceptance: retry admission now.
40 : : * Neither acceptance nor polling reserves capacity.
41 : : * Connection loss ends a blocked wait with NotReady; cancellation by stop
42 : : * ends it with CancelledWhileWaiting. Retain the first terminal cause on
43 : : * the connection record, under the same lock as these events, even when
44 : : * stop, loss and reconnect all happen before the next poll.
45 : : */
46 : : [[nodiscard]] virtual std::optional<wrapper::SendResult> poll_capacity() = 0;
47 : :
48 : : // Validate the pinned connection and admit atomically. WouldBlock is the only
49 : : // retryable refusal. Rejected moves retain their input; rejected shared writes
50 : : // retain no ownership. Acceptance means local queue admission, not delivery.
51 : : [[nodiscard]] virtual wrapper::SendResult write_copy(memory::ConstByteSpan data) = 0;
52 : : [[nodiscard]] virtual wrapper::SendResult write_move(std::vector<uint8_t>&& data) = 0;
53 : : [[nodiscard]] virtual wrapper::SendResult write_shared(std::shared_ptr<const std::vector<uint8_t>> data) = 0;
54 : : };
55 : :
56 : : /**
57 : : * Optional custom Channel capability for connection-pinned Reliable sends.
58 : : *
59 : : * ResultChannel supplies nonblocking admission. This extension additionally
60 : : * supplies atomic connection capture, capacity polling and pinned admission.
61 : : * Client wrapper injection requires this capability or its matching native transport.
62 : : */
63 : : class WIRESTEAD_API ConnectionChannel : public ResultChannel {
64 : : public:
65 : : using Connection = std::shared_ptr<WriteConnection>;
66 : : using CaptureResult = std::variant<wrapper::SendRejection, Connection>;
67 : :
68 : : // Check readiness and capture the current connection in one decision. Return
69 : : // an actual rejection or a non-null handle, never an unpinned success.
70 : : [[nodiscard]] virtual CaptureResult capture_write_connection() = 0;
71 : :
72 : : // Called before wrapper stop releases waiters. Serialize with capture, loss
73 : : // and admission; preserve an earlier terminal cause. Do not invoke callbacks
74 : : // inline or wait for an executor. Channel::stop must cancel waits too when
75 : : // the transport is stopped directly.
76 : : virtual void cancel_write_waits() = 0;
77 : : };
78 : :
79 : : } // namespace wirestead::interface
|