Increase timeouts for Exchange sync; prevent early upload sync
* It's reported that 50% of third party users have issues syncing Calendar in Exchange * In testing, it was determined that the server takes > 30 seconds to respond to a sync request initially, which is beyond our timeout limit * Also, I found that the system SyncManager was trying to trigger an upload sync at the same time (i.e. before the sync session was established with the server) * There are four changes here: 1) Prevent upload syncs while the sync key is null or "0" ("0" is the initial state) 2) Increase timeout for connection; at worst, this will cause a short extra delay in syncs with a bad connection, but this will be unnoticable to users 3) Increase the read timeout for initial sync to twice that of regular syncs (the initial sync always seems to take longer) 3) Reduce the lookback for calendar to two weeks (from one month); this is a better default anyway, and it probably reduces the server and client load a great deal * Empirically, this solves the bug for a known completely repeatable case. Bug: 2569162 Change-Id: I36b1c3e1e0b65f50d42e05f1830fed912191651f
This commit is contained in:
parent
c3aa318200
commit
2e22263777
|
@ -45,6 +45,10 @@ public class CalendarSyncAdapterService extends Service {
|
|||
MailboxColumns.ACCOUNT_KEY + "=? AND " + MailboxColumns.TYPE + '=' + Mailbox.TYPE_CALENDAR;
|
||||
private static final String DIRTY_IN_ACCOUNT =
|
||||
Events._SYNC_DIRTY + "=1 AND " + Events._SYNC_ACCOUNT + "=?";
|
||||
private static final String[] ID_SYNC_KEY_PROJECTION =
|
||||
new String[] {MailboxColumns.ID, MailboxColumns.SYNC_KEY};
|
||||
private static final int ID_SYNC_KEY_MAILBOX_ID = 0;
|
||||
private static final int ID_SYNC_KEY_SYNC_KEY = 1;
|
||||
|
||||
public CalendarSyncAdapterService() {
|
||||
super();
|
||||
|
@ -119,15 +123,22 @@ public class CalendarSyncAdapterService extends Service {
|
|||
if (accountCursor.moveToFirst()) {
|
||||
long accountId = accountCursor.getLong(0);
|
||||
// Now, find the calendar mailbox associated with the account
|
||||
Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, EmailContent.ID_PROJECTION,
|
||||
Cursor mailboxCursor = cr.query(Mailbox.CONTENT_URI, ID_SYNC_KEY_PROJECTION,
|
||||
ACCOUNT_AND_TYPE_CALENDAR, new String[] {Long.toString(accountId)}, null);
|
||||
try {
|
||||
if (mailboxCursor.moveToFirst()) {
|
||||
if (logging) {
|
||||
Log.d(TAG, "Upload sync requested for " + account.name);
|
||||
}
|
||||
String syncKey = mailboxCursor.getString(ID_SYNC_KEY_SYNC_KEY);
|
||||
if ((syncKey == null) || (syncKey.equals("0"))) {
|
||||
if (logging) {
|
||||
Log.d(TAG, "Can't sync; mailbox in initial state");
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Ask for a sync from our sync manager
|
||||
SyncManager.serviceRequest(mailboxCursor.getLong(0),
|
||||
SyncManager.serviceRequest(mailboxCursor.getLong(ID_SYNC_KEY_MAILBOX_ID),
|
||||
SyncManager.SYNC_UPSYNC);
|
||||
}
|
||||
} finally {
|
||||
|
|
|
@ -120,7 +120,14 @@ public class EasSyncService extends AbstractSyncService {
|
|||
static private final int CHUNK_SIZE = 16*1024;
|
||||
|
||||
static private final String PING_COMMAND = "Ping";
|
||||
// Command timeout is the the time allowed for reading data from an open connection before an
|
||||
// IOException is thrown. After a small added allowance, our watchdog alarm goes off (allowing
|
||||
// us to detect a silently dropped connection). The allowance is defined below.
|
||||
static private final int COMMAND_TIMEOUT = 20*SECONDS;
|
||||
// Connection timeout is the time given to connect to the server before reporting an IOException
|
||||
static private final int CONNECTION_TIMEOUT = 30*SECONDS;
|
||||
// The extra time allowed beyond the COMMAND_TIMEOUT before which our watchdog alarm triggers
|
||||
static private final int WATCHDOG_TIMEOUT_ALLOWANCE = 10*SECONDS;
|
||||
|
||||
static private final String AUTO_DISCOVER_SCHEMA_PREFIX =
|
||||
"http://schemas.microsoft.com/exchange/autodiscover/mobilesync/";
|
||||
|
@ -1034,7 +1041,7 @@ public class EasSyncService extends AbstractSyncService {
|
|||
|
||||
private HttpClient getHttpClient(int timeout) {
|
||||
HttpParams params = new BasicHttpParams();
|
||||
HttpConnectionParams.setConnectionTimeout(params, 15*SECONDS);
|
||||
HttpConnectionParams.setConnectionTimeout(params, CONNECTION_TIMEOUT);
|
||||
HttpConnectionParams.setSoTimeout(params, timeout);
|
||||
HttpConnectionParams.setSocketBufferSize(params, 8192);
|
||||
HttpClient client = new DefaultHttpClient(getClientConnectionManager(), params);
|
||||
|
@ -1078,7 +1085,7 @@ public class EasSyncService extends AbstractSyncService {
|
|||
boolean isPingCommand) throws IOException {
|
||||
synchronized(getSynchronizer()) {
|
||||
mPendingPost = method;
|
||||
long alarmTime = timeout+(10*SECONDS);
|
||||
long alarmTime = timeout + WATCHDOG_TIMEOUT_ALLOWANCE;
|
||||
if (isPingCommand) {
|
||||
SyncManager.runAsleep(mMailboxId, alarmTime);
|
||||
} else {
|
||||
|
@ -1878,9 +1885,14 @@ public class EasSyncService extends AbstractSyncService {
|
|||
.data(Tags.SYNC_COLLECTION_ID, mailbox.mServerId)
|
||||
.tag(Tags.SYNC_DELETES_AS_MOVES);
|
||||
|
||||
// EAS doesn't like GetChanges if the syncKey is "0"; not documented
|
||||
// Start with the default timeout
|
||||
int timeout = COMMAND_TIMEOUT;
|
||||
if (!syncKey.equals("0")) {
|
||||
// EAS doesn't like GetChanges if the syncKey is "0"; not documented
|
||||
s.tag(Tags.SYNC_GET_CHANGES);
|
||||
} else {
|
||||
// Use 2x timeout for initial sync, which empirically can take a while longer
|
||||
timeout <<= 1;
|
||||
}
|
||||
s.data(Tags.SYNC_WINDOW_SIZE,
|
||||
className.equals("Email") ? EMAIL_WINDOW_SIZE : PIM_WINDOW_SIZE);
|
||||
|
@ -1891,8 +1903,8 @@ public class EasSyncService extends AbstractSyncService {
|
|||
if (className.equals("Email")) {
|
||||
s.data(Tags.SYNC_FILTER_TYPE, getEmailFilter());
|
||||
} else if (className.equals("Calendar")) {
|
||||
// TODO Force one month for calendar until we can set this!
|
||||
s.data(Tags.SYNC_FILTER_TYPE, Eas.FILTER_1_MONTH);
|
||||
// TODO Force two weeks for calendar until we can set this!
|
||||
s.data(Tags.SYNC_FILTER_TYPE, Eas.FILTER_2_WEEKS);
|
||||
}
|
||||
// Set the truncation amount for all classes
|
||||
if (mProtocolVersionDouble >= Eas.SUPPORTED_PROTOCOL_EX2007_DOUBLE) {
|
||||
|
@ -1911,7 +1923,8 @@ public class EasSyncService extends AbstractSyncService {
|
|||
target.sendLocalChanges(s);
|
||||
|
||||
s.end().end().end().done();
|
||||
HttpResponse resp = sendHttpClientPost("Sync", s.toByteArray());
|
||||
HttpResponse resp = sendHttpClientPost("Sync", new ByteArrayEntity(s.toByteArray()),
|
||||
timeout);
|
||||
int code = resp.getStatusLine().getStatusCode();
|
||||
if (code == HttpStatus.SC_OK) {
|
||||
InputStream is = resp.getEntity().getContent();
|
||||
|
|
Loading…
Reference in New Issue