@Override public <R, E extends Throwable> R doRetryable( final IRetryableTask<R, E> task, final IRetryStrategy strategy) throws RetryerException, InterruptedException { checkArgument(task != null, "task can't be null"); checkArgument(strategy != null, "strategy can't be null"); int tryNo = 0; final List<Throwable> reasons = Lists.newArrayList(); MDC.put("task", task.toString()); try { while (true) { try { log.debug("try #{}...", tryNo); if (Thread.interrupted()) { throw new InterruptedException("Interrupted on " + tryNo + " try"); } return task.execute(tryNo); } catch (InterruptedException e) { log.debug("try #{} interrupted: {}", tryNo, e.getMessage()); throw e; } catch (final Throwable reason) { log.debug("try #{} failed: {}", tryNo, reason.getMessage()); reasons.add(reason); // cleanup if (task.isFatalReason(tryNo, reason)) { throw new RetryerException(reasons); } final RetryInfo retryInfo = strategy.shouldRetry(tryNo, reason); if (retryInfo.shouldFail()) { throw new RetryerException(reasons); } else { final long delay = retryInfo.delay(); if (delay > 0) { log.debug("retry after {} ms", delay); Thread.sleep(delay); } else { log.debug("retry now"); } } } finally { tryNo++; } } } finally { MDC.remove("task"); } }
public void onPatchServiceStart(Intent intent) { if (!isRetryEnable) { TinkerLog.w(TAG, "onPatchServiceStart retry disabled, just return"); return; } if (intent == null) { TinkerLog.e(TAG, "onPatchServiceStart intent is null, just return"); return; } boolean isUpgrade = TinkerPatchService.getPatchUpgradeExtra(intent); if (!isUpgrade) { TinkerLog.w(TAG, "onPatchServiceStart is not upgrade patch, just return"); return; } String path = TinkerPatchService.getPatchPathExtra(intent); if (path == null) { TinkerLog.w(TAG, "onPatchServiceStart patch path is null, just return"); return; } RetryInfo retryInfo; File patchFile = new File(path); String patchMd5 = SharePatchFileUtil.getMD5(patchFile); if (patchMd5 == null) { TinkerLog.w(TAG, "onPatchServiceStart patch md5 is null, just return"); return; } if (retryInfoFile.exists()) { retryInfo = RetryInfo.readRetryProperty(retryInfoFile); if (retryInfo.md5 == null || retryInfo.times == null || !patchMd5.equals(retryInfo.md5)) { copyToTempFile(patchFile); retryInfo.md5 = patchMd5; retryInfo.times = "1"; } else { int nowTimes = Integer.parseInt(retryInfo.times); if (nowTimes >= RETRY_MAX_COUNT) { SharePatchFileUtil.safeDeleteFile(retryInfoFile); SharePatchFileUtil.safeDeleteFile(tempPatchFile); TinkerLog.w( TAG, "onPatchServiceStart retry more than max count, delete retry info file!"); return; } else { retryInfo.times = String.valueOf(nowTimes + 1); } } } else { copyToTempFile(patchFile); retryInfo = new RetryInfo(patchMd5, "1"); } RetryInfo.writeRetryProperty(retryInfoFile, retryInfo); }