use of org.thoughtcrime.securesms.util.Stopwatch in project Signal-Android by signalapp.
the class RetrieveProfileJob method onRun.
@Override
public void onRun() throws IOException, RetryLaterException {
if (!SignalStore.account().isRegistered()) {
Log.w(TAG, "Unregistered. Skipping.");
return;
}
Stopwatch stopwatch = new Stopwatch("RetrieveProfile");
RecipientDatabase recipientDatabase = SignalDatabase.recipients();
RecipientUtil.ensureUuidsAreAvailable(context, Stream.of(Recipient.resolvedList(recipientIds)).filter(r -> r.getRegistered() != RecipientDatabase.RegisteredState.NOT_REGISTERED).toList());
List<Recipient> recipients = Recipient.resolvedList(recipientIds);
stopwatch.split("resolve-ensure");
ProfileService profileService = new ProfileService(ApplicationDependencies.getGroupsV2Operations().getProfileOperations(), ApplicationDependencies.getSignalServiceMessageReceiver(), ApplicationDependencies.getSignalWebSocket());
List<Observable<Pair<Recipient, ServiceResponse<ProfileAndCredential>>>> requests = Stream.of(recipients).filter(Recipient::hasServiceId).map(r -> ProfileUtil.retrieveProfile(context, r, getRequestType(r), profileService).toObservable()).toList();
stopwatch.split("requests");
OperationState operationState = Observable.mergeDelayError(requests).observeOn(Schedulers.io(), true).scan(new OperationState(), (state, pair) -> {
Recipient recipient = pair.first();
ProfileService.ProfileResponseProcessor processor = new ProfileService.ProfileResponseProcessor(pair.second());
if (processor.hasResult()) {
state.profiles.add(processor.getResult(recipient));
} else if (processor.notFound()) {
Log.w(TAG, "Failed to find a profile for " + recipient.getId());
if (recipient.isRegistered()) {
state.unregistered.add(recipient.getId());
}
} else if (processor.genericIoError()) {
state.retries.add(recipient.getId());
} else {
Log.w(TAG, "Failed to retrieve profile for " + recipient.getId());
}
return state;
}).lastOrError().blockingGet();
stopwatch.split("responses");
Set<RecipientId> success = SetUtil.difference(recipientIds, operationState.retries);
Map<RecipientId, ServiceId> newlyRegistered = Stream.of(operationState.profiles).map(Pair::first).filterNot(Recipient::isRegistered).collect(Collectors.toMap(Recipient::getId, r -> r.getServiceId().orNull()));
// noinspection SimplifyStreamApiCallChains
Util.chunk(operationState.profiles, 150).stream().forEach(list -> {
SignalDatabase.runInTransaction(() -> {
for (Pair<Recipient, ProfileAndCredential> profile : list) {
process(profile.first(), profile.second());
}
});
});
recipientDatabase.markProfilesFetched(success, System.currentTimeMillis());
if (operationState.unregistered.size() > 0 || newlyRegistered.size() > 0) {
Log.i(TAG, "Marking " + newlyRegistered.size() + " users as registered and " + operationState.unregistered.size() + " users as unregistered.");
recipientDatabase.bulkUpdatedRegisteredStatus(newlyRegistered, operationState.unregistered);
}
stopwatch.split("process");
for (Pair<Recipient, ProfileAndCredential> profile : operationState.profiles) {
setIdentityKey(profile.first(), profile.second().getProfile().getIdentityKey());
}
stopwatch.split("identityKeys");
long keyCount = Stream.of(operationState.profiles).map(Pair::first).map(Recipient::getProfileKey).withoutNulls().count();
Log.d(TAG, String.format(Locale.US, "Started with %d recipient(s). Found %d profile(s), and had keys for %d of them. Will retry %d.", recipients.size(), operationState.profiles.size(), keyCount, operationState.retries.size()));
stopwatch.stop(TAG);
recipientIds.clear();
recipientIds.addAll(operationState.retries);
if (recipientIds.size() > 0) {
throw new RetryLaterException();
}
}
use of org.thoughtcrime.securesms.util.Stopwatch in project Signal-Android by signalapp.
the class PaymentSendJob method onRun.
@Override
protected void onRun() throws Exception {
if (!Recipient.self().isRegistered()) {
throw new NotPushRegisteredException();
}
if (!SignalStore.paymentsValues().mobileCoinPaymentsEnabled()) {
Log.w(TAG, "Payments are not enabled");
return;
}
Stopwatch stopwatch = new Stopwatch("Payment submission");
Wallet wallet = ApplicationDependencies.getPayments().getWallet();
PaymentDatabase paymentDatabase = SignalDatabase.payments();
paymentDatabase.createOutgoingPayment(uuid, recipientId, publicAddress, timestamp, note, amount);
Log.i(TAG, "Payment record created " + uuid);
stopwatch.split("Record created");
try {
PaymentSubmissionResult paymentSubmissionResult = wallet.sendPayment(publicAddress, amount.requireMobileCoin(), totalFee.requireMobileCoin());
stopwatch.split("Payment submitted");
if (paymentSubmissionResult.containsDefrags()) {
Log.i(TAG, "Payment contains " + paymentSubmissionResult.defrags().size() + " defrags, main payment" + uuid);
RecipientId self = Recipient.self().getId();
MobileCoinPublicAddress selfAddress = wallet.getMobileCoinPublicAddress();
for (TransactionSubmissionResult defrag : paymentSubmissionResult.defrags()) {
UUID defragUuid = UUID.randomUUID();
PaymentTransactionId.MobileCoin mobileCoinTransaction = (PaymentTransactionId.MobileCoin) defrag.getTransactionId();
paymentDatabase.createDefrag(defragUuid, self, selfAddress, timestamp - 1, mobileCoinTransaction.getFee(), mobileCoinTransaction.getTransaction(), mobileCoinTransaction.getReceipt());
Log.i(TAG, "Defrag entered with id " + defragUuid);
ApplicationDependencies.getJobManager().startChain(new PaymentTransactionCheckJob(defragUuid, QUEUE)).then(new MultiDeviceOutgoingPaymentSyncJob(defragUuid)).enqueue();
}
stopwatch.split("Defrag");
}
TransactionSubmissionResult.ErrorCode errorCode = paymentSubmissionResult.getErrorCode();
switch(errorCode) {
case INSUFFICIENT_FUNDS:
paymentDatabase.markPaymentFailed(uuid, FailureReason.INSUFFICIENT_FUNDS);
throw new PaymentException("Payment failed due to " + errorCode);
case GENERIC_FAILURE:
paymentDatabase.markPaymentFailed(uuid, FailureReason.UNKNOWN);
throw new PaymentException("Payment failed due to " + errorCode);
case NETWORK_FAILURE:
paymentDatabase.markPaymentFailed(uuid, FailureReason.NETWORK);
throw new PaymentException("Payment failed due to " + errorCode);
case NONE:
Log.i(TAG, "Payment submission complete");
TransactionSubmissionResult transactionSubmissionResult = Objects.requireNonNull(paymentSubmissionResult.getNonDefrag());
PaymentTransactionId.MobileCoin mobileCoinTransaction = (PaymentTransactionId.MobileCoin) transactionSubmissionResult.getTransactionId();
paymentDatabase.markPaymentSubmitted(uuid, mobileCoinTransaction.getTransaction(), mobileCoinTransaction.getReceipt(), mobileCoinTransaction.getFee());
Log.i(TAG, "Payment record updated " + uuid);
break;
}
} catch (Exception e) {
Log.w(TAG, "Unknown payment failure", e);
paymentDatabase.markPaymentFailed(uuid, FailureReason.UNKNOWN);
throw e;
}
stopwatch.split("Update database record");
stopwatch.stop(TAG);
}
Aggregations