Add 10s timeout to user facing CDSI requests.
This commit is contained in:
parent
8d20669e46
commit
36fc9aa82a
8 changed files with 34 additions and 15 deletions
|
@ -59,6 +59,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
@ -121,7 +122,7 @@ public class NewConversationActivity extends ContactSelectionActivity
|
|||
if (!resolved.isRegistered() || !resolved.hasServiceId()) {
|
||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.");
|
||||
try {
|
||||
ContactDiscovery.refresh(this, resolved, false);
|
||||
ContactDiscovery.refresh(this, resolved, false, TimeUnit.SECONDS.toMillis(10));
|
||||
resolved = Recipient.resolved(resolved.getId());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.");
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.thoughtcrime.securesms.util.views.SimpleProgressDialog
|
|||
import java.io.IOException
|
||||
import java.util.Optional
|
||||
import java.util.function.Consumer
|
||||
import kotlin.time.Duration.Companion.seconds
|
||||
|
||||
class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment.NewCallCallback {
|
||||
|
||||
|
@ -49,7 +50,7 @@ class NewCallActivity : ContactSelectionActivity(), ContactSelectionListFragment
|
|||
if (!resolved.isRegistered || !resolved.hasServiceId()) {
|
||||
Log.i(TAG, "[onContactSelected] Not registered or no UUID. Doing a directory refresh.")
|
||||
resolved = try {
|
||||
refresh(this, resolved, false)
|
||||
refresh(this, resolved, false, 10.seconds.inWholeMilliseconds)
|
||||
Recipient.resolved(resolved.id)
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "[onContactSelected] Failed to refresh directory for new contact.")
|
||||
|
|
|
@ -91,14 +91,15 @@ object ContactDiscovery {
|
|||
}
|
||||
|
||||
@JvmStatic
|
||||
@JvmOverloads
|
||||
@Throws(IOException::class)
|
||||
@WorkerThread
|
||||
fun refresh(context: Context, recipient: Recipient, notifyOfNewUsers: Boolean): RecipientTable.RegisteredState {
|
||||
fun refresh(context: Context, recipient: Recipient, notifyOfNewUsers: Boolean, timeoutMs: Long? = null): RecipientTable.RegisteredState {
|
||||
val result: RefreshResult = refreshRecipients(
|
||||
context = context,
|
||||
descriptor = "refresh-single",
|
||||
refresh = {
|
||||
ContactDiscoveryRefreshV2.refresh(context, listOf(recipient), useCompat = !FeatureFlags.phoneNumberPrivacy(), ignoreResults = false)
|
||||
ContactDiscoveryRefreshV2.refresh(context, listOf(recipient), useCompat = !FeatureFlags.phoneNumberPrivacy(), ignoreResults = false, timeoutMs = timeoutMs)
|
||||
},
|
||||
removeSystemContactLinksIfMissing = false,
|
||||
notifyOfNewUsers = notifyOfNewUsers
|
||||
|
|
|
@ -49,7 +49,7 @@ object ContactDiscoveryRefreshV2 {
|
|||
@WorkerThread
|
||||
@Synchronized
|
||||
@JvmStatic
|
||||
fun refreshAll(context: Context, useCompat: Boolean, ignoreResults: Boolean): ContactDiscovery.RefreshResult {
|
||||
fun refreshAll(context: Context, useCompat: Boolean, ignoreResults: Boolean, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
||||
val recipientE164s: Set<String> = SignalDatabase.recipients.getAllE164s().sanitize()
|
||||
val systemE164s: Set<String> = SystemContactsRepository.getAllDisplayNumbers(context).toE164s(context).sanitize()
|
||||
|
||||
|
@ -59,7 +59,8 @@ object ContactDiscoveryRefreshV2 {
|
|||
inputPreviousE164s = SignalDatabase.cds.getAllE164s(),
|
||||
isPartialRefresh = false,
|
||||
useCompat = useCompat,
|
||||
ignoreResults = ignoreResults
|
||||
ignoreResults = ignoreResults,
|
||||
timeoutMs = timeoutMs
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -67,14 +68,14 @@ object ContactDiscoveryRefreshV2 {
|
|||
@WorkerThread
|
||||
@Synchronized
|
||||
@JvmStatic
|
||||
fun refresh(context: Context, inputRecipients: List<Recipient>, useCompat: Boolean, ignoreResults: Boolean): ContactDiscovery.RefreshResult {
|
||||
fun refresh(context: Context, inputRecipients: List<Recipient>, useCompat: Boolean, ignoreResults: Boolean, timeoutMs: Long? = null): ContactDiscovery.RefreshResult {
|
||||
val recipients: List<Recipient> = inputRecipients.map { it.resolve() }
|
||||
val inputE164s: Set<String> = recipients.mapNotNull { it.e164.orElse(null) }.toSet().sanitize()
|
||||
|
||||
return if (inputE164s.size > MAXIMUM_ONE_OFF_REQUEST_SIZE) {
|
||||
Log.i(TAG, "List of specific recipients to refresh is too large! (Size: ${recipients.size}). Doing a full refresh instead.")
|
||||
|
||||
val fullResult: ContactDiscovery.RefreshResult = refreshAll(context, useCompat = useCompat, ignoreResults = ignoreResults)
|
||||
val fullResult: ContactDiscovery.RefreshResult = refreshAll(context, useCompat = useCompat, ignoreResults = ignoreResults, timeoutMs = timeoutMs)
|
||||
val inputIds: Set<RecipientId> = recipients.map { it.id }.toSet()
|
||||
|
||||
ContactDiscovery.RefreshResult(
|
||||
|
@ -88,7 +89,8 @@ object ContactDiscoveryRefreshV2 {
|
|||
inputPreviousE164s = emptySet(),
|
||||
isPartialRefresh = true,
|
||||
useCompat = useCompat,
|
||||
ignoreResults = ignoreResults
|
||||
ignoreResults = ignoreResults,
|
||||
timeoutMs = timeoutMs
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +102,8 @@ object ContactDiscoveryRefreshV2 {
|
|||
inputPreviousE164s: Set<String>,
|
||||
isPartialRefresh: Boolean,
|
||||
useCompat: Boolean,
|
||||
ignoreResults: Boolean
|
||||
ignoreResults: Boolean,
|
||||
timeoutMs: Long? = null
|
||||
): ContactDiscovery.RefreshResult {
|
||||
val tag = "refreshInternal-${if (useCompat) "compat" else "v2"}"
|
||||
val stopwatch = Stopwatch(tag)
|
||||
|
@ -134,7 +137,8 @@ object ContactDiscoveryRefreshV2 {
|
|||
SignalDatabase.recipients.getAllServiceIdProfileKeyPairs(),
|
||||
useCompat,
|
||||
Optional.ofNullable(token),
|
||||
BuildConfig.CDSI_MRENCLAVE
|
||||
BuildConfig.CDSI_MRENCLAVE,
|
||||
timeoutMs
|
||||
) { tokenToSave ->
|
||||
stopwatch.split("network-pre-token")
|
||||
if (!isPartialRefresh) {
|
||||
|
|
|
@ -723,7 +723,7 @@ public class ConversationParentFragment extends Fragment
|
|||
case ADD_CONTACT:
|
||||
SimpleTask.run(() -> {
|
||||
try {
|
||||
ContactDiscovery.refresh(requireContext(), recipient.get(), false);
|
||||
ContactDiscovery.refresh(requireContext(), recipient.get(), false, TimeUnit.SECONDS.toMillis(10));
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to refresh user after adding to contacts.");
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.io.IOException;
|
|||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
@ -160,7 +161,7 @@ public class CreateGroupActivity extends ContactSelectionActivity {
|
|||
|
||||
for (Recipient recipient : registeredChecks) {
|
||||
try {
|
||||
ContactDiscovery.refresh(this, recipient, false);
|
||||
ContactDiscovery.refresh(this, recipient, false, TimeUnit.SECONDS.toMillis(10));
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Failed to refresh registered status for " + recipient.getId(), e);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ import org.whispersystems.signalservice.api.push.ServiceId;
|
|||
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CommunicationActions {
|
||||
|
||||
|
@ -303,7 +304,7 @@ public class CommunicationActions {
|
|||
|
||||
if (!recipient.isRegistered() || !recipient.hasServiceId()) {
|
||||
try {
|
||||
ContactDiscovery.refresh(activity, recipient, false);
|
||||
ContactDiscovery.refresh(activity, recipient, false, TimeUnit.SECONDS.toMillis(10));
|
||||
recipient = Recipient.resolved(recipient.getId());
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "[handlePotentialSignalMeUrl] Failed to refresh directory for new contact.");
|
||||
|
|
|
@ -390,6 +390,7 @@ public class SignalServiceAccountManager {
|
|||
boolean requireAcis,
|
||||
Optional<byte[]> token,
|
||||
String mrEnclave,
|
||||
Long timeoutMs,
|
||||
Consumer<byte[]> tokenSaver)
|
||||
throws IOException
|
||||
{
|
||||
|
@ -400,11 +401,20 @@ public class SignalServiceAccountManager {
|
|||
|
||||
ServiceResponse<CdsiV2Service.Response> serviceResponse;
|
||||
try {
|
||||
serviceResponse = single.blockingGet();
|
||||
if (timeoutMs == null) {
|
||||
serviceResponse = single
|
||||
.blockingGet();
|
||||
} else {
|
||||
serviceResponse = single
|
||||
.timeout(timeoutMs, TimeUnit.MILLISECONDS)
|
||||
.blockingGet();
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
Throwable cause = e.getCause();
|
||||
if (cause instanceof InterruptedException) {
|
||||
throw new IOException("Interrupted", cause);
|
||||
} else if (cause instanceof TimeoutException) {
|
||||
throw new IOException("Timed out");
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue