]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
neorados: Refactor cls exec API to use compile time policing. Deprecated old API.
authorAlex Ainscow <aainscow@uk.ibm.com>
Mon, 24 Nov 2025 16:47:10 +0000 (16:47 +0000)
committerAlex Ainscow <aainscow@uk.ibm.com>
Fri, 28 Nov 2025 08:41:38 +0000 (08:41 +0000)
Signed-off-by: Alex Ainscow <aainscow@uk.ibm.com>
src/include/neorados/RADOS.hpp
src/neorados/RADOS.cc

index 5dfc51a33b13703d250cdec1a7eeff6f852e663a..b5de1beb1e397e9d0d0a9e16395fe045f9ce6b2c 100644 (file)
@@ -64,6 +64,9 @@
 
 #include "common/ceph_time.h"
 
+// For compile-time policing of class calls.
+#include "include/rados/cls_traits.h"
+
 namespace neorados {
 class Object;
 class IOContext;
@@ -352,22 +355,64 @@ public:
   void assert_exists();
   void cmp_omap(const std::vector<cmp_assertion>& assertions);
 
+  [[deprecated("in favor of compile-time safe ops")]]
   void exec(std::string_view cls, std::string_view method,
-           const ceph::buffer::list& inbl,
-           ceph::buffer::list* out,
-           boost::system::error_code* ec = nullptr);
+            const ceph::buffer::list& inbl,
+            ceph::buffer::list* out,
+            boost::system::error_code* ec = nullptr);
+
+  [[deprecated("in favor of compile-time safe ops")]]
   void exec(std::string_view cls, std::string_view method,
-           const ceph::buffer::list& inbl,
-           fu2::unique_function<void(boost::system::error_code,
-                                     const ceph::buffer::list&) &&> f);
+            const ceph::buffer::list& inbl,
+            fu2::unique_function<void(boost::system::error_code,
+                                      const ceph::buffer::list&) &&> f);
+  [[deprecated("in favor of compile-time safe ops")]]
   void exec(std::string_view cls, std::string_view method,
-           const ceph::buffer::list& inbl,
-           fu2::unique_function<void(boost::system::error_code, int,
-                                     const ceph::buffer::list&) &&> f);
+            const ceph::buffer::list& inbl,
+            fu2::unique_function<void(boost::system::error_code, int,
+                                      const ceph::buffer::list&) &&> f);
+  [[deprecated("in favor of compile-time safe ops")]]
   void exec(std::string_view cls, std::string_view method,
-           const ceph::buffer::list& inbl,
-           boost::system::error_code* ec = nullptr);
-
+            const ceph::buffer::list& inbl,
+            boost::system::error_code* ec = nullptr);
+
+ protected:
+  // These methods being protected is part of the compile-time protection for
+  // read/write execs.
+  void exec_impl(std::string_view cls, std::string_view method,
+            const ceph::buffer::list& inbl,
+            ceph::buffer::list* out,
+            boost::system::error_code* ec);
+
+  void exec_impl(std::string_view cls, std::string_view method,
+            const ceph::buffer::list& inbl,
+            fu2::unique_function<void(boost::system::error_code,
+                                      const ceph::buffer::list&) &&> f);
+  void exec_impl(std::string_view cls, std::string_view method,
+            const ceph::buffer::list& inbl,
+            fu2::unique_function<void(boost::system::error_code, int,
+                                      const ceph::buffer::list&) &&> f);
+  void exec_impl(std::string_view cls, std::string_view method,
+            const ceph::buffer::list& inbl,
+            boost::system::error_code* ec);
+  // templates don't work well with default arguments.
+  void exec_impl(std::string_view cls, std::string_view method,
+          const ceph::buffer::list& inbl) {
+    exec_impl(cls, method, inbl, (boost::system::error_code*)nullptr);
+  }
+  void exec_impl(std::string_view cls, std::string_view method,
+          const ceph::buffer::list& inbl,
+          ceph::buffer::list* out) {
+    exec_impl(cls, method, inbl, out, (boost::system::error_code*)nullptr);
+  }
+ public:
+
+  template <typename Tag, typename ClassID, typename... Args>
+  void exec(const ClsMethod<Tag, ClassID>& method, const ceph::buffer::list& inbl, Args&&... args) {
+    static_assert(FlagTraits<Tag>::is_readonly,
+      "Attempt to call a non-readonly class method as part of a non-write op ");
+    exec_impl(method.cls, method.name, inbl, std::forward<Args>(args)...);
+  }
 
   // Flags that apply to all ops in the operation vector
   void balance_reads();
@@ -649,6 +694,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               ceph::buffer::list* out,
@@ -656,6 +702,7 @@ public:
     Op::exec(cls, method, inbl, out, ec);
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                ceph::buffer::list* out,
@@ -664,6 +711,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               fu2::unique_function<void(boost::system::error_code,
@@ -671,6 +719,7 @@ public:
     Op::exec(cls, method, inbl, std::move(f));
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                fu2::unique_function<void(boost::system::error_code,
@@ -679,6 +728,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               fu2::unique_function<void(boost::system::error_code, int,
@@ -686,6 +736,7 @@ public:
     Op::exec(cls, method, inbl, std::move(f));
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                fu2::unique_function<void(boost::system::error_code, int,
@@ -694,12 +745,14 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               boost::system::error_code* ec = nullptr) & {
     Op::exec(cls, method, inbl, ec);
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   ReadOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                boost::system::error_code* ec = nullptr) && {
@@ -707,6 +760,22 @@ public:
     return std::move(*this);
   }
 
+  template <typename Tag, typename ClassID, typename... Args>
+  ReadOp& exec(const ClsMethod<Tag, ClassID>& method, Args&&... args) & {
+    static_assert(FlagTraits<Tag>::is_readonly,
+      "Attempt to call a non-readonly class method as part of read. ");
+    Op::exec_impl(method.cls, method.name, std::forward<Args>(args)...);
+    return *this;
+  }
+
+  template <typename Tag, typename ClassID, typename... Args>
+  ReadOp&& exec(const ClsMethod<Tag, ClassID>& method, Args&&... args) && {
+    static_assert(FlagTraits<Tag>::is_readonly,
+      "Attempt to call a non-readonly class method as part of read. ");
+    Op::exec_impl(method.cls, method.name, std::forward<Args>(args)...);
+    return std::move(*this);
+  }
+
   template<typename F>
   ReadOp& exec(ClsOp<F>&& clsop) & {
     return clsop(*this);
@@ -1029,6 +1098,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               ceph::buffer::list* out,
@@ -1036,6 +1106,7 @@ public:
     Op::exec(cls, method, inbl, out, ec);
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                ceph::buffer::list* out,
@@ -1044,6 +1115,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               fu2::unique_function<void(boost::system::error_code,
@@ -1051,6 +1123,7 @@ public:
     Op::exec(cls, method, inbl, std::move(f));
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                fu2::unique_function<void(boost::system::error_code,
@@ -1059,6 +1132,7 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               fu2::unique_function<void(boost::system::error_code, int,
@@ -1066,6 +1140,7 @@ public:
     Op::exec(cls, method, inbl, std::move(f));
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                fu2::unique_function<void(boost::system::error_code, int,
@@ -1074,12 +1149,14 @@ public:
     return std::move(*this);
   }
 
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp& exec(std::string_view cls, std::string_view method,
               const ceph::buffer::list& inbl,
               boost::system::error_code* ec = nullptr) & {
     Op::exec(cls, method, inbl, ec);
     return *this;
   }
+  [[deprecated("in favor of compile-time safe ops")]]
   WriteOp&& exec(std::string_view cls, std::string_view method,
                const ceph::buffer::list& inbl,
                boost::system::error_code* ec = nullptr) && {
@@ -1087,6 +1164,18 @@ public:
     return std::move(*this);
   }
 
+  template <typename Tag, typename ClassID, typename... Args>
+  decltype(auto) exec(const ClsMethod<Tag, ClassID>& method, const ceph::buffer::list& inbl, Args&&... args) & {
+    Op::exec_impl(method.cls, method.name, inbl, std::forward<Args>(args)...);
+    return *this;
+  }
+
+  template <typename Tag, typename ClassID, typename... Args>
+  decltype(auto) exec(const ClsMethod<Tag, ClassID>& method, const ceph::buffer::list& inbl, Args&&... args) && {
+    Op::exec_impl(method.cls, method.name, inbl, std::forward<Args>(args)...);
+    return std::move(*this);
+  }
+
   template<typename F>
   WriteOp& exec(ClsOp<F>&& clsop) & {
     return clsop(*this);
index 3824e3fe6c3dfc1d07bcaf1a7a74071d9dbe9531..e36fc39f7d7c2b720bad442d47b2ce55f88cae8d 100644 (file)
@@ -517,6 +517,28 @@ void Op::exec(std::string_view cls, std::string_view method,
              const bufferlist& inbl, bs::error_code* ec) {
   reinterpret_cast<OpImpl*>(&impl)->op.call(cls, method, inbl, ec);
 }
+void Op::exec_impl(std::string_view cls, std::string_view method,
+              const bufferlist& inbl,
+              cb::list* out,
+              bs::error_code* ec) {
+  reinterpret_cast<OpImpl*>(&impl)->op.call(cls, method, inbl, ec, out);
+}
+void Op::exec_impl(std::string_view cls, std::string_view method,
+              const bufferlist& inbl,
+              fu2::unique_function<void(bs::error_code,
+                                        const cb::list&) &&> f) {
+  reinterpret_cast<OpImpl*>(&impl)->op.call(cls, method, inbl, std::move(f));
+}
+void Op::exec_impl(std::string_view cls, std::string_view method,
+              const bufferlist& inbl,
+              fu2::unique_function<void(bs::error_code, int,
+                                        const cb::list&) &&> f) {
+  reinterpret_cast<OpImpl*>(&impl)->op.call(cls, method, inbl, std::move(f));
+}
+void Op::exec_impl(std::string_view cls, std::string_view method,
+              const bufferlist& inbl, bs::error_code* ec) {
+  reinterpret_cast<OpImpl*>(&impl)->op.call(cls, method, inbl, ec);
+}
 
 void Op::balance_reads() {
   reinterpret_cast<OpImpl*>(&impl)->op.flags |= CEPH_OSD_FLAG_BALANCE_READS;