diff options
author | eldritch horrors <pennae@lix.systems> | 2024-03-04 04:35:39 +0100 |
---|---|---|
committer | eldritch horrors <pennae@lix.systems> | 2024-03-04 04:37:05 +0100 |
commit | e12e9f2452681a3036884e9e778154b35246d39e (patch) | |
tree | 57aaea8bf74c53e28fba9598cea034e9b08ce9f5 /src/libstore/serve-protocol.hh | |
parent | aeb803de9ad3cd449f7dc85588430ed5b21503eb (diff) |
Merge pull request #9137 from obsidiansystems/serve-protocol
Introduce separate Serve protocol serialisers
(cherry picked from commit d070d8b7460f412a657745698dba291c66792402)
Change-Id: Ibcc8639e8997bcd07f7a5318330a147bcadc411b
Diffstat (limited to 'src/libstore/serve-protocol.hh')
-rw-r--r-- | src/libstore/serve-protocol.hh | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/libstore/serve-protocol.hh b/src/libstore/serve-protocol.hh index 7e43b3969..e2345d450 100644 --- a/src/libstore/serve-protocol.hh +++ b/src/libstore/serve-protocol.hh @@ -1,6 +1,8 @@ #pragma once ///@file +#include "common-protocol.hh" + namespace nix { #define SERVE_MAGIC_1 0x390c9deb @@ -10,6 +12,11 @@ namespace nix { #define GET_PROTOCOL_MAJOR(x) ((x) & 0xff00) #define GET_PROTOCOL_MINOR(x) ((x) & 0x00ff) + +class Store; +struct Source; + + /** * The "serve protocol", used by ssh:// stores. * @@ -22,6 +29,57 @@ struct ServeProto * Enumeration of all the request types for the protocol. */ enum struct Command : uint64_t; + + /** + * A unidirectional read connection, to be used by the read half of the + * canonical serializers below. + * + * This currently is just a `Source &`, but more fields will be added + * later. + */ + struct ReadConn { + Source & from; + }; + + /** + * A unidirectional write connection, to be used by the write half of the + * canonical serializers below. + * + * This currently is just a `Sink &`, but more fields will be added + * later. + */ + struct WriteConn { + Sink & to; + }; + + /** + * Data type for canonical pairs of serialisers for the serve protocol. + * + * See https://en.cppreference.com/w/cpp/language/adl for the broader + * concept of what is going on here. + */ + template<typename T> + struct Serialise; + // This is the definition of `Serialise` we *want* to put here, but + // do not do so. + // + // See `worker-protocol.hh` for a longer explanation. +#if 0 + { + static T read(const Store & store, ReadConn conn); + static void write(const Store & store, WriteConn conn, const T & t); + }; +#endif + + /** + * Wrapper function around `ServeProto::Serialise<T>::write` that allows us to + * infer the type instead of having to write it down explicitly. + */ + template<typename T> + static void write(const Store & store, WriteConn conn, const T & t) + { + ServeProto::Serialise<T>::write(store, conn, t); + } }; enum struct ServeProto::Command : uint64_t @@ -58,4 +116,33 @@ inline std::ostream & operator << (std::ostream & s, ServeProto::Command op) return s << (uint64_t) op; } +/** + * Declare a canonical serialiser pair for the worker protocol. + * + * We specialise the struct merely to indicate that we are implementing + * the function for the given type. + * + * Some sort of `template<...>` must be used with the caller for this to + * be legal specialization syntax. See below for what that looks like in + * practice. + */ +#define DECLARE_SERVE_SERIALISER(T) \ + struct ServeProto::Serialise< T > \ + { \ + static T read(const Store & store, ServeProto::ReadConn conn); \ + static void write(const Store & store, ServeProto::WriteConn conn, const T & t); \ + }; + +template<typename T> +DECLARE_SERVE_SERIALISER(std::vector<T>); +template<typename T> +DECLARE_SERVE_SERIALISER(std::set<T>); +template<typename... Ts> +DECLARE_SERVE_SERIALISER(std::tuple<Ts...>); + +#define COMMA_ , +template<typename K, typename V> +DECLARE_SERVE_SERIALISER(std::map<K COMMA_ V>); +#undef COMMA_ + } |