mirror of https://github.com/commaai/openpilot.git
updated: only fetch on metered connection when necessary (#31041)
* updated: only fetch on metered connection when necessary * button always fetches
This commit is contained in:
parent
d36103791c
commit
4c2bb9f380
|
@ -161,6 +161,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||
{"NavPastDestinations", PERSISTENT},
|
||||
{"NavSettingLeftSide", PERSISTENT},
|
||||
{"NavSettingTime24h", PERSISTENT},
|
||||
{"NetworkMetered", PERSISTENT},
|
||||
{"ObdMultiplexingChanged", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"ObdMultiplexingEnabled", CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION},
|
||||
{"Offroad_BadNvme", CLEAR_ON_MANAGER_START},
|
||||
|
@ -201,6 +202,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
|||
{"UpdaterNewReleaseNotes", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterState", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterTargetBranch", CLEAR_ON_MANAGER_START},
|
||||
{"UpdaterLastFetchTime", PERSISTENT},
|
||||
{"Version", PERSISTENT},
|
||||
{"VisionRadarToggle", PERSISTENT},
|
||||
{"WheeledBody", PERSISTENT},
|
||||
|
|
|
@ -447,6 +447,8 @@ def thermald_thread(end_event, hw_queue) -> None:
|
|||
except Exception:
|
||||
cloudlog.exception("failed to save offroad status")
|
||||
|
||||
params.put_bool_nonblocking("NetworkMetered", (msg.deviceState.networkType != NetworkType.wifi))
|
||||
|
||||
count += 1
|
||||
should_start_prev = should_start
|
||||
|
||||
|
|
|
@ -35,26 +35,42 @@ OVERLAY_INIT = Path(os.path.join(BASEDIR, ".overlay_init"))
|
|||
DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
|
||||
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
|
||||
|
||||
class UserRequest:
|
||||
NONE = 0
|
||||
CHECK = 1
|
||||
FETCH = 2
|
||||
|
||||
class WaitTimeHelper:
|
||||
def __init__(self):
|
||||
self.ready_event = threading.Event()
|
||||
self.only_check_for_update = False
|
||||
self.user_request = UserRequest.NONE
|
||||
signal.signal(signal.SIGHUP, self.update_now)
|
||||
signal.signal(signal.SIGUSR1, self.check_now)
|
||||
|
||||
def update_now(self, signum: int, frame) -> None:
|
||||
cloudlog.info("caught SIGHUP, attempting to downloading update")
|
||||
self.only_check_for_update = False
|
||||
self.user_request = UserRequest.FETCH
|
||||
self.ready_event.set()
|
||||
|
||||
def check_now(self, signum: int, frame) -> None:
|
||||
cloudlog.info("caught SIGUSR1, checking for updates")
|
||||
self.only_check_for_update = True
|
||||
self.user_request = UserRequest.CHECK
|
||||
self.ready_event.set()
|
||||
|
||||
def sleep(self, t: float) -> None:
|
||||
self.ready_event.wait(timeout=t)
|
||||
|
||||
def write_time_to_param(params, param) -> None:
|
||||
t = datetime.datetime.utcnow()
|
||||
params.put(param, t.isoformat().encode('utf8'))
|
||||
|
||||
def read_time_from_param(params, param) -> Optional[datetime.datetime]:
|
||||
t = params.get(param, encoding='utf8')
|
||||
try:
|
||||
return datetime.datetime.fromisoformat(t)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
return None
|
||||
|
||||
def run(cmd: List[str], cwd: Optional[str] = None) -> str:
|
||||
return subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT, encoding='utf8')
|
||||
|
@ -266,14 +282,11 @@ class Updater:
|
|||
|
||||
last_update = datetime.datetime.utcnow()
|
||||
if update_success:
|
||||
t = last_update.isoformat()
|
||||
self.params.put("LastUpdateTime", t.encode('utf8'))
|
||||
write_time_to_param(self.params, "LastUpdateTime")
|
||||
else:
|
||||
try:
|
||||
t = self.params.get("LastUpdateTime", encoding='utf8')
|
||||
last_update = datetime.datetime.fromisoformat(t)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
t = read_time_from_param(self.params, "LastUpdateTime")
|
||||
if t is not None:
|
||||
last_update = t
|
||||
|
||||
if exception is None:
|
||||
self.params.remove("LastUpdateException")
|
||||
|
@ -421,10 +434,7 @@ def main() -> None:
|
|||
|
||||
updater = Updater()
|
||||
update_failed_count = 0 # TODO: Load from param?
|
||||
|
||||
# no fetch on the first time
|
||||
wait_helper = WaitTimeHelper()
|
||||
wait_helper.only_check_for_update = True
|
||||
|
||||
# invalidate old finalized update
|
||||
set_consistent_flag(False)
|
||||
|
@ -458,10 +468,16 @@ def main() -> None:
|
|||
updater.check_for_update()
|
||||
|
||||
# download update
|
||||
if wait_helper.only_check_for_update:
|
||||
cloudlog.info("skipping fetch this cycle")
|
||||
last_fetch = read_time_from_param(params, "UpdaterLastFetchTime")
|
||||
timed_out = last_fetch is None or (datetime.datetime.utcnow() - last_fetch > datetime.timedelta(days=3))
|
||||
user_requested_fetch = wait_helper.user_request == UserRequest.FETCH
|
||||
if params.get_bool("NetworkMetered") and not timed_out and not user_requested_fetch:
|
||||
cloudlog.info("skipping fetch, connection metered")
|
||||
elif wait_helper.user_request == UserRequest.CHECK:
|
||||
cloudlog.info("skipping fetch, only checking")
|
||||
else:
|
||||
updater.fetch_update()
|
||||
write_time_to_param(params, "UpdaterLastFetchTime")
|
||||
update_failed_count = 0
|
||||
except subprocess.CalledProcessError as e:
|
||||
cloudlog.event(
|
||||
|
@ -485,7 +501,7 @@ def main() -> None:
|
|||
cloudlog.exception("uncaught updated exception while setting params, shouldn't happen")
|
||||
|
||||
# infrequent attempts if we successfully updated recently
|
||||
wait_helper.only_check_for_update = False
|
||||
wait_helper.user_request = UserRequest.NONE
|
||||
wait_helper.sleep(5*60 if update_failed_count > 0 else 1.5*60*60)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue