1 /*
2 * Copyright 2022 Google LLC
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 #include "fcp/client/opstats/opstats_utils.h"
18
19 #include <algorithm>
20 #include <optional>
21 #include <string>
22
23 #include "google/protobuf/timestamp.pb.h"
24 #include "fcp/base/monitoring.h"
25 #include "fcp/client/opstats/opstats_db.h"
26 #include "fcp/protos/opstats.pb.h"
27
28 namespace fcp {
29 namespace client {
30 namespace opstats {
31
GetLastSuccessfulContributionTime(OpStatsSequence & data,const std::string & task_name)32 std::optional<google::protobuf::Timestamp> GetLastSuccessfulContributionTime(
33 OpStatsSequence& data, const std::string& task_name) {
34 std::optional<OperationalStats> last_successful_entry =
35 GetLastSuccessfulContribution(data, task_name);
36 if (!last_successful_entry.has_value()) {
37 return std::nullopt;
38 }
39
40 auto upload_started = std::find_if(
41 last_successful_entry->events().begin(),
42 last_successful_entry->events().end(),
43 [](const OperationalStats::Event& event) {
44 return event.event_type() ==
45 OperationalStats::Event::EVENT_KIND_RESULT_UPLOAD_STARTED;
46 });
47 if (upload_started == last_successful_entry->events().end()) {
48 // For last_successful_entry to have a value, it must have had an
49 // EVENT_KIND_RESULT_UPLOAD_STARTED event, so we should never reach this.
50 return std::nullopt;
51 }
52
53 return upload_started->timestamp();
54 }
55
GetLastSuccessfulContribution(OpStatsSequence & data,const std::string & task_name)56 std::optional<OperationalStats> GetLastSuccessfulContribution(
57 OpStatsSequence& data, const std::string& task_name) {
58 for (auto it = data.opstats().rbegin(); it != data.opstats().rend(); ++it) {
59 const OperationalStats& opstats_entry = *it;
60 bool upload_started = false;
61 bool upload_aborted = false;
62 if (opstats_entry.task_name() != task_name) {
63 continue;
64 }
65 for (const auto& event : opstats_entry.events()) {
66 if (event.event_type() ==
67 OperationalStats::Event::EVENT_KIND_RESULT_UPLOAD_STARTED) {
68 upload_started = true;
69 }
70 if (event.event_type() ==
71 OperationalStats::Event::EVENT_KIND_RESULT_UPLOAD_SERVER_ABORTED) {
72 upload_aborted = true;
73 }
74 }
75 if (upload_started && !upload_aborted) {
76 return opstats_entry;
77 }
78 }
79 return std::nullopt;
80 }
81
82 } // namespace opstats
83 } // namespace client
84 } // namespace fcp
85