1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef DFSU_CMD_H
17 #define DFSU_CMD_H
18 
19 #include <functional>
20 
21 #include "dfsu_exception.h"
22 
23 namespace OHOS {
24 namespace Storage {
25 namespace DistributedFile {
26 enum class CmdImportance {
27     // If it fails(even has tried multiple times), shutdown the actor.
28     VITAL,
29 
30     SUBVITAL,
31     // If it fails(even has tried multiple times), reboot the actor.
32     NORMAL,
33 
34     // If it fails(may also try multiple times), just do nothing.
35     TRIVIAL,
36 };
37 
38 struct CmdOptions {
39     CmdImportance importance_ { CmdImportance::TRIVIAL };
40     uint32_t tryTimes_ {1};
41 };
42 
43 template<typename T>
44 class DfsuActor;
45 
46 template<typename Ctx>
47 class VirtualCmd {
48     friend class DfsuActor<Ctx>;
49 
50 public:
51     VirtualCmd() = default;
52     virtual ~VirtualCmd() = default;
53     virtual void operator()(Ctx *ctx) = 0;
54 
UpdateOption(CmdOptions op)55     void UpdateOption(CmdOptions op)
56     {
57         option_ = op;
58     }
59 
60 protected:
61     CmdOptions option_;
62 };
63 
64 template<typename Ctx, typename... Args>
65 class DfsuCmd : public VirtualCmd<Ctx> {
66     friend class DfsuActor<Ctx>;
67 
68 public:
DfsuCmd(void (Ctx::* f)(Args...),Args...args)69     DfsuCmd(void (Ctx::*f)(Args...), Args... args) : f_(f), args_(args...) {}
70     ~DfsuCmd() override = default;
71 
72 private:
73     void (Ctx::*f_)(Args...);
74     std::tuple<Args...> args_;
75 
operator()76     void operator()(Ctx *ctx) override
77     {
78         if (!VirtualCmd<Ctx>::option_.tryTimes_) {
79             ThrowException(ERR_UTILS_ACTOR_INVALID_CMD, "Cannot execute a command that has 0 try times");
80         }
81 
82         VirtualCmd<Ctx>::option_.tryTimes_--;
83         std::apply(f_, std::tuple_cat(std::make_tuple(ctx), args_));
84     }
85 };
86 } // namespace DistributedFile
87 } // namespace Storage
88 } // namespace OHOS
89 #endif // DFSU_CMD_H