blob: 1a94ac3f4ea3a2c3f53d12db0492cef901e7dd5b [file] [log] [blame]
Philippe Hamel409d3e072017-11-07 22:55:141// Copyright 2017 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Philippe Hamel69564832017-11-22 20:39:485#ifndef COMPONENTS_ASSIST_RANKER_RANKER_MODEL_LOADER_IMPL_H_
6#define COMPONENTS_ASSIST_RANKER_RANKER_MODEL_LOADER_IMPL_H_
Philippe Hamel409d3e072017-11-07 22:55:147
Philippe Hamel69564832017-11-22 20:39:488#include "components/assist_ranker/ranker_model_loader.h"
Philippe Hamel409d3e072017-11-07 22:55:149
10#include <memory>
11#include <string>
12
13#include "base/callback.h"
14#include "base/files/file_path.h"
15#include "base/memory/ref_counted.h"
16#include "base/memory/weak_ptr.h"
17#include "base/sequence_checker.h"
18#include "base/time/time.h"
Philippe Hamel409d3e072017-11-07 22:55:1419#include "url/gurl.h"
20
21namespace base {
22class SequencedTaskRunner;
23} // namespace base
24
Mark Pilgrim389b08f2018-05-30 13:20:1325namespace network {
26class SharedURLLoaderFactory;
27}
28
Philippe Hamel69564832017-11-22 20:39:4829namespace assist_ranker {
Philippe Hamel409d3e072017-11-07 22:55:1430
31class RankerURLFetcher;
32
33// Loads a ranker model. Will attempt to load the model from disk cache. If it
34// fails, will attempt to download from the given URL.
35class RankerModelLoaderImpl : public RankerModelLoader {
36 public:
37 // |validate_model_callback| may be called on any sequence; it must be thread
38 // safe.
39 //
40 // |on_model_available_callback| will be called on the sequence on which the
41 // ranker model loader is constructed.
42 //
43 // |model_path| denotes the file path at which the model is cached. The loader
44 // will attempt to load the model from this path first, falling back to the
45 // |model_url| if the model cannot be loaded or has expired. Upon downloading
46 // a fresh model from |model_url| the model will be persisted to |model_path|
47 // for subsequent caching.
48 //
49 // |model_url| denotes the URL from which the model should be loaded, if it
50 // has not already been cached at |model_path|.
51 //
52 // |uma_prefix| will be used as a prefix for the names of all UMA metrics
53 // generated by this loader.
Mark Pilgrim389b08f2018-05-30 13:20:1354 RankerModelLoaderImpl(
55 ValidateModelCallback validate_model_callback,
56 OnModelAvailableCallback on_model_available_callback,
57 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
58 base::FilePath model_path,
59 GURL model_url,
60 std::string uma_prefix);
Philippe Hamel409d3e072017-11-07 22:55:1461
62 ~RankerModelLoaderImpl() override;
63
64 // Call this method periodically to notify the model loader the ranker is
65 // actively in use. The user's engagement with the ranked feature is used
66 // as a proxy for network availability and activity. If a model download
67 // is pending, this will trigger (subject to retry and frequency limits) a
68 // model download attempt.
69 void NotifyOfRankerActivity() override;
70
71 private:
72 // A enum to track the current loader state.
73 enum class LoaderState {
74 // The loader is newly created and has not started trying to load the model.
75 // This state can transition to LOADING_FROM_FILE or, if |model_path_| is
76 // empty, to LOADING_FROM_URL. If both |model_path_| and |model_url_| are
77 // empty/invalid then it can transition to FINISHED.
78 NOT_STARTED,
79 // The loader is busy loading the model from |model_path_| in the
80 // background. This state can transition to FINISHED if the loaded model is
81 // compatible and up to date; otherwise, this state can transition to IDLE.
82 LOADING_FROM_FILE,
83 // The loader is not currently busy. The loader can transition to the
84 // LOADING_FROM_URL_ state if |model_url_| is valid; the loader can also
85 // transition to FINISHED if it the maximum number of download attempts
86 // has been reached.
87 IDLE,
88 // The loader is busy loading the model from |model_url_| in the background.
89 // This state can transition to FINISHED if the loaded model is valid;
90 // otherwise, this state can re-transition to IDLE.
91 LOADING_FROM_URL,
92 // The loader has finished. This is the terminal state.
93 FINISHED
94 };
95
96 // Asynchronously initiates loading the model from model_path_;
97 void StartLoadFromFile();
98
99 // Called when the background worker has finished loading |data| from
100 // |model_path_|. If |data| is empty, the load from |model_path_| failed.
101 void OnFileLoaded(const std::string& data);
102
103 // Asynchronously initiates loading the model from |model_url_|.
104 void StartLoadFromURL();
105
106 // Called when |url_fetcher_| has finished loading |data| from |model_url_|.
107 //
108 // This call signature is mandated by RankerURLFetcher.
109 //
110 // success - true of the download was successful
111 // data - the body of the downloads response
112 void OnURLFetched(bool success, const std::string& data);
113
114 // Parse |data| and return a validated model. Returns nullptr on failure.
Philippe Hamel69564832017-11-22 20:39:48115 std::unique_ptr<assist_ranker::RankerModel> CreateAndValidateModel(
Philippe Hamel409d3e072017-11-07 22:55:14116 const std::string& data);
117
118 // Helper function to log |model_status| to UMA and return it.
119 RankerModelStatus ReportModelStatus(RankerModelStatus model_status);
120
121 // Validates that ranker model loader tasks are all performed on the same
122 // sequence.
123 SEQUENCE_CHECKER(sequence_checker_);
124
125 // The task runner on which background tasks are performed.
126 const scoped_refptr<base::SequencedTaskRunner> background_task_runner_;
127
128 // Validates a ranker model on behalf of the model loader client. This will be
129 // called on the sequence on which the model leader was constructed.
130 const ValidateModelCallback validate_model_cb_;
131
132 // Transfers ownership of a loaded model back to the model loader client.
133 // This will be called on the sequence on which the model loader was
134 // constructed.
135 const OnModelAvailableCallback on_model_available_cb_;
136
Mark Pilgrim389b08f2018-05-30 13:20:13137 // URL loader factory used for RankerURLFetcher.
138 scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
Philippe Hamel409d3e072017-11-07 22:55:14139
140 // The path at which the model is (or should be) cached.
141 const base::FilePath model_path_;
142
143 // The URL from which to download the model if the model is not in the cache
144 // or the cached model is invalid/expired.
145 const GURL model_url_;
146
147 // This will prefix all UMA metrics generated by the model loader.
148 const std::string uma_prefix_;
149
150 // Used to download model data from |model_url_|.
151 std::unique_ptr<RankerURLFetcher> url_fetcher_;
152
153 // The next time before which no new attempts to download the model should be
154 // attempted.
155 base::TimeTicks next_earliest_download_time_;
156
157 // Tracks the last time of the last attempt to load a model, either from file
158 // of from URL. Used for UMA reporting of load durations.
159 base::TimeTicks load_start_time_;
160
161 // The current state of the loader.
162 LoaderState state_ = LoaderState::NOT_STARTED;
163
164 // Creates weak pointer references to the loader.
165 base::WeakPtrFactory<RankerModelLoaderImpl> weak_ptr_factory_;
166
167 DISALLOW_COPY_AND_ASSIGN(RankerModelLoaderImpl);
168};
169
Philippe Hamel69564832017-11-22 20:39:48170} // namespace assist_ranker
Philippe Hamel409d3e072017-11-07 22:55:14171
Philippe Hamel69564832017-11-22 20:39:48172#endif // COMPONENTS_ASSIST_RANKER_RANKER_MODEL_LOADER_IMPL_H_