Github user achristianson commented on a diff in the pull request:
https://github.com/apache/nifi-minifi-cpp/pull/134#discussion_r137866433
--- Diff: libminifi/include/core/state/UpdateController.h ---
@@ -0,0 +1,255 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifndef LIBMINIFI_INCLUDE_C2_UPDATECONTROLLER_H_
+#define LIBMINIFI_INCLUDE_C2_UPDATECONTROLLER_H_
+
+#include <string>
+#include "utils/ThreadPool.h"
+
+namespace org {
+namespace apache {
+namespace nifi {
+namespace minifi {
+namespace state {
+
+enum class UpdateState {
+ INITIATE,
+ FULLY_APPLIED,
+ READ_COMPLETE,
+ PARTIALLY_APPLIED,
+ NOT_APPLIED,
+ SET_ERROR,
+ READ_ERROR,
+ NESTED // multiple updates embedded into one
+
+};
+
+/**
+ * Represents the status of an update operation.
+ *
+ */
+class UpdateStatus {
+ public:
+ UpdateStatus(UpdateState state, int16_t reason = 0);
+
+ UpdateStatus(const UpdateStatus &other);
+
+ UpdateStatus(const UpdateStatus &&other);
+
+ UpdateState getState() const;
+
+ std::string getError() const;
+
+ int16_t getReadonCode() const;
+
+ UpdateStatus &operator=(const UpdateStatus &&other);
+
+ UpdateStatus &operator=(const UpdateStatus &other);
+ private:
+ UpdateState state_;
+ std::string error_;
+ int16_t reason_;
+};
+
+class Update
+{
+ public:
+
+ Update(UpdateStatus status)
+ : status_(status) {
+
+ }
+
+ Update(const Update &other)
+ : status_(other.status_) {
+
+ }
+
+ Update(const Update &&other)
+ : status_(std::move(other.status_)) {
+
+ }
+
+ virtual ~Update() {
+
+ }
+
+ virtual bool validate() {
+ return true;
+ }
+
+ const UpdateStatus &getStatus() const {
+ return status_;
+ }
+
+ Update &operator=(const Update &&other) {
+ status_ = std::move(other.status_);
+ return *this;
+ }
+
+ Update &operator=(const Update &other) {
+ status_ = other.status_;
+ return *this;
+ }
+
+ protected:
+ UpdateStatus status_;
+};
+
+/**
+ * Justification and Purpose: Update Runner reflects the post execution
functors that determine if
+ * a given function that is running within a thread pool worker needs to
end.
+ *
+ * Design: Simply implements isFinished and isCancelled, which it receives
by way of the AfterExecute
+ * class.
+ */
+class UpdateRunner : public utils::AfterExecute<Update>
+{
+ public:
+ explicit UpdateRunner(std::atomic<bool> &running)
+ : running_(&running) {
+ }
+
+ explicit UpdateRunner(UpdateRunner && other)
+ : running_(std::move(other.running_)) {
+
+ }
+
+ ~UpdateRunner() {
+
+ }
+
+ virtual bool isFinished(const Update &result) {
+ if ((result.getStatus().getState() == UpdateState::FULLY_APPLIED ||
result.getStatus().getState() == UpdateState::READ_COMPLETE) && *running_) {
--- End diff --
As a general note, it seems we're building up quite a bit of
concurrent/mutex/async code. Wondering if we can simplify a bit by using
queues/workers to reduce context switching and also reduce the chances of
contention.
---