blob: d6558596ed9cf50d03635f39bc85cc908bade54d [file] [log] [blame]
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef FEDERATED_FEDERATED_CLIENT_H_
#define FEDERATED_FEDERATED_CLIENT_H_
#include <string>
#include <fcp/fcp.h>
#include "federated/device_status/device_status_monitor.h"
#include "federated/example_database.h"
#include "federated/federated_metadata.h"
#include "federated/storage_manager.h"
namespace federated {
// FederatedClient encapsulates essential elements for a client to run
// federated tasks, e.g. the function ptr from the library(`run_plan_`,
// `free_run_plan_result_`), the server config, the client_config.
class FederatedClient {
public:
// FederatedLibrary::CreateClient should be used instead of this constructor.
FederatedClient(FlRunPlanFn run_plan,
FlFreeRunPlanResultFn free_run_plan_result,
const std::string& service_uri,
const std::string& api_key,
const std::string& brella_lib_version,
ClientConfigMetadata client_config,
const DeviceStatusMonitor* device_status_monitor);
FederatedClient& operator=(const FederatedClient&) = delete;
~FederatedClient();
// Tries to checkin and start a federated task with the server, then updates
// the client config, such as retry_token and next_retry_delay. It is
// scheduled recurrently by Scheduler, see scheduler.cc for more details.
void RunPlan(const StorageManager* storage_manager);
// Resets `next_retry_delay_` to default. Called when current
// `next_retry_delay_` elapses and a federated task is about to run.
void ResetRetryDelay();
std::string GetClientName() const;
base::TimeDelta next_retry_delay() const { return next_retry_delay_; }
private:
// Context provides several static functions used in constructing
// FlTaskEnvironment that serves as hook for the library to e.g. request
// examples.
// All the methods on this are static and take a void* context because this is
// meant to be passed across as a C ABI.
class Context {
public:
Context(const std::string& client_name,
const std::string& table_name,
const std::string& population_name,
const DeviceStatusMonitor* device_status_monitor,
const StorageManager* storage_manager);
Context(const Context&) = delete;
Context& operator=(const Context&) = delete;
~Context();
MetaRecord& new_meta_record() { return new_meta_record_; }
// Called by the library to prepare examples according to the criteria.
static bool PrepareExamples(const char* const criteria_data,
int criteria_data_size,
void* context);
// Called by the library to get next example. `context` is effectively a
// pointer to an Context instance, the same to the following methods.
// Returns true if no errors, caller can construct a serialized example with
// `data` and `size` if `end` is false, or it knows examples run out.
// Returns false if any errors.
static bool GetNextExample(const char** data,
int* const size,
bool* const end,
void* const context);
// Called by the library to free the char* returned by GetNextExample.
static void FreeExample(const char* const data, void* const context);
// Called by the library to inquiry whether the current task should continue
// or quit early.
static bool TrainingConditionsSatisfied(void* const context);
// Called by the library to publish event logs out to the daemon.
static void PublishEvent(const char* const event,
const int size,
void* const context);
private:
// `client_name_` represents the unique identifier of a federated client.
// It's used for metrices, meta records.
const std::string client_name_;
// `table_name_` is for preparing examples from the example storage for the
// federated tasks.
const std::string table_name_;
// `population_name_` on the other hand, is an identifier that can be
// recognized by the server side when the device checks in. It consists of a
// fixed prefix "chromeos", the client name, and the launch stage, separated
// by "/". The launch stage can be "dev", "dogfood", "internal", "prod",
// etc. e.g. population_name = "chromeos/timezone_code_phh/dev".
const std::string population_name_;
// New meta record that will be updated to Metatable if contribution
// succeeds.
MetaRecord new_meta_record_;
// The time the context instance is created, used in
// `TrainingConditionsSatisfied` to early stop if the task takes too long.
const base::Time start_time_;
// Not owned:
const DeviceStatusMonitor* const device_status_monitor_;
const StorageManager* const storage_manager_;
ExampleDatabase::Iterator example_iterator_;
};
const FlRunPlanFn run_plan_;
const FlFreeRunPlanResultFn free_run_plan_result_;
const std::string service_uri_;
const std::string api_key_;
const std::string brella_lib_version_;
ClientConfigMetadata client_config_;
base::TimeDelta next_retry_delay_;
// Not owned:
const DeviceStatusMonitor* const device_status_monitor_;
};
} // namespace federated
#endif // FEDERATED_FEDERATED_CLIENT_H_