Merge change 24722 into eclair

* changes:
  Fix connection failure retry behavior; don't try syncing w/o connectivity
This commit is contained in:
Android (Google) Code Review 2009-09-11 16:09:43 -04:00
commit 2bab07c71e
2 changed files with 37 additions and 23 deletions

View File

@ -551,7 +551,6 @@ public class EasSyncService extends AbstractSyncService {
if (len > 0) { if (len > 0) {
InputStream is = entity.getContent(); InputStream is = entity.getContent();
// Returns true if we need to sync again // Returns true if we need to sync again
userLog("FolderSync, deviceId = ", mDeviceId);
if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this)) if (new FolderSyncParser(is, new AccountSyncAdapter(mMailbox, this))
.parse()) { .parse()) {
continue; continue;
@ -764,8 +763,8 @@ public class EasSyncService extends AbstractSyncService {
// try increasing timeout by two minutes // try increasing timeout by two minutes
if ((status == PROTOCOL_PING_STATUS_COMPLETED) && if ((status == PROTOCOL_PING_STATUS_COMPLETED) &&
(pingHeartbeat > mPingHighWaterMark)) { (pingHeartbeat > mPingHighWaterMark)) {
userLog("Setting ping high water mark at: ", mPingHighWaterMark);
mPingHighWaterMark = pingHeartbeat; mPingHighWaterMark = pingHeartbeat;
userLog("Setting ping high water mark at: ", mPingHighWaterMark);
} }
if ((status == PROTOCOL_PING_STATUS_COMPLETED) && if ((status == PROTOCOL_PING_STATUS_COMPLETED) &&
(pingHeartbeat < PING_MAX_HEARTBEAT) && (pingHeartbeat < PING_MAX_HEARTBEAT) &&
@ -962,7 +961,6 @@ public class EasSyncService extends AbstractSyncService {
target.sendLocalChanges(s); target.sendLocalChanges(s);
s.end().end().end().done(); s.end().end().end().done();
userLog("Sync, deviceId = ", mDeviceId);
HttpResponse resp = sendHttpClientPost("Sync", s.toByteArray()); HttpResponse resp = sendHttpClientPost("Sync", s.toByteArray());
int code = resp.getStatusLine().getStatusCode(); int code = resp.getStatusLine().getStatusCode();
if (code == HttpStatus.SC_OK) { if (code == HttpStatus.SC_OK) {

View File

@ -117,8 +117,7 @@ public class SyncManager extends Service implements Runnable {
private static final int CONNECTIVITY_WAIT_TIME = 10*MINUTES; private static final int CONNECTIVITY_WAIT_TIME = 10*MINUTES;
// Sync hold constants for services with transient errors // Sync hold constants for services with transient errors
private static final int HOLD_DELAY_ESCALATION = 30*SECONDS; private static final int HOLD_DELAY_MAXIMUM = 4*MINUTES;
private static final int HOLD_DELAY_MAXIMUM = 3*MINUTES;
// Reason codes when SyncManager.kick is called (mainly for debugging) // Reason codes when SyncManager.kick is called (mainly for debugging)
// UI has changed data, requiring an upsync of changes // UI has changed data, requiring an upsync of changes
@ -166,6 +165,7 @@ public class SyncManager extends Service implements Runnable {
private static Object sSyncToken = new Object(); private static Object sSyncToken = new Object();
// All threads can use this lock to wait for connectivity // All threads can use this lock to wait for connectivity
public static Object sConnectivityLock = new Object(); public static Object sConnectivityLock = new Object();
public static boolean sConnectivityHold = false;
// Keeps track of running services (by mailbox id) // Keeps track of running services (by mailbox id)
private HashMap<Long, AbstractSyncService> mServiceMap = private HashMap<Long, AbstractSyncService> mServiceMap =
@ -203,6 +203,8 @@ public class SyncManager extends Service implements Runnable {
// The reason for SyncManager's next wakeup call // The reason for SyncManager's next wakeup call
private String mNextWaitReason; private String mNextWaitReason;
// Whether we have an unsatisfied "kick" pending
private boolean mKicked = false;
// Receiver of connectivity broadcasts // Receiver of connectivity broadcasts
private ConnectivityReceiver mConnectivityReceiver = null; private ConnectivityReceiver mConnectivityReceiver = null;
@ -572,21 +574,20 @@ public class SyncManager extends Service implements Runnable {
class SyncError { class SyncError {
int reason; int reason;
boolean fatal = false; boolean fatal = false;
long holdEndTime; long holdDelay = 15*SECONDS;
long holdDelay = 0; long holdEndTime = System.currentTimeMillis() + holdDelay;
SyncError(int _reason, boolean _fatal) { SyncError(int _reason, boolean _fatal) {
reason = _reason; reason = _reason;
fatal = _fatal; fatal = _fatal;
escalate();
} }
/** /**
* We increase the hold on I/O errors in 30 second increments to 5 minutes * We double the holdDelay from 15 seconds through 4 mins
*/ */
void escalate() { void escalate() {
if (holdDelay < HOLD_DELAY_MAXIMUM) { if (holdDelay < HOLD_DELAY_MAXIMUM) {
holdDelay += HOLD_DELAY_ESCALATION; holdDelay *= 2;
} }
holdEndTime = System.currentTimeMillis() + holdDelay; holdEndTime = System.currentTimeMillis() + holdDelay;
} }
@ -1081,6 +1082,8 @@ public class SyncManager extends Service implements Runnable {
} }
private void startService(Mailbox m, int reason, PartRequest req) { private void startService(Mailbox m, int reason, PartRequest req) {
// Don't sync if there's no connectivity
if (sConnectivityHold) return;
synchronized (sSyncToken) { synchronized (sSyncToken) {
Account acct = Account.restoreAccountWithId(this, m.mAccountKey); Account acct = Account.restoreAccountWithId(this, m.mAccountKey);
if (acct != null) { if (acct != null) {
@ -1126,7 +1129,7 @@ public class SyncManager extends Service implements Runnable {
(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo(); NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null) { if (info != null) {
log("NetworkInfo: " + info.getTypeName() + ", " + info.getState().name()); //log("NetworkInfo: " + info.getTypeName() + ", " + info.getState().name());
return; return;
} else { } else {
@ -1141,9 +1144,12 @@ public class SyncManager extends Service implements Runnable {
runAsleep(SYNC_MANAGER_ID, CONNECTIVITY_WAIT_TIME+5*SECONDS); runAsleep(SYNC_MANAGER_ID, CONNECTIVITY_WAIT_TIME+5*SECONDS);
try { try {
log("Connectivity lock..."); log("Connectivity lock...");
sConnectivityHold = true;
sConnectivityLock.wait(CONNECTIVITY_WAIT_TIME); sConnectivityLock.wait(CONNECTIVITY_WAIT_TIME);
log("Connectivity lock released..."); log("Connectivity lock released...");
} catch (InterruptedException e) { } catch (InterruptedException e) {
} finally {
sConnectivityHold = false;
} }
runAwake(SYNC_MANAGER_ID); runAwake(SYNC_MANAGER_ID);
} }
@ -1193,20 +1199,29 @@ public class SyncManager extends Service implements Runnable {
long nextWait = checkMailboxes(); long nextWait = checkMailboxes();
try { try {
synchronized (this) { synchronized (this) {
if (nextWait < 0) { if (!mKicked) {
log("Negative wait? Setting to 1s"); if (nextWait < 0) {
nextWait = 1*SECONDS; log("Negative wait? Setting to 1s");
nextWait = 1*SECONDS;
}
if (nextWait > 30*SECONDS) {
runAsleep(SYNC_MANAGER_ID, nextWait - 1000);
}
if (nextWait != SYNC_MANAGER_HEARTBEAT_TIME) {
log("Next awake in " + nextWait / 1000 + "s: " + mNextWaitReason);
}
wait(nextWait);
} }
if (nextWait > 30*SECONDS) {
runAsleep(SYNC_MANAGER_ID, nextWait - 1000);
}
if (nextWait != SYNC_MANAGER_HEARTBEAT_TIME) {
log("Next awake in " + nextWait / 1000 + "s: " + mNextWaitReason);
}
wait(nextWait);
} }
} catch (InterruptedException e) { } catch (InterruptedException e) {
// Needs to be caught, but causes no problem // Needs to be caught, but causes no problem
} finally {
synchronized (this) {
if (mKicked) {
//log("Wait deferred due to kick");
mKicked = false;
}
}
} }
} }
stopServices(); stopServices();
@ -1314,8 +1329,8 @@ public class SyncManager extends Service implements Runnable {
} }
continue; continue;
} else { } else {
// The hold has ended; remove from the error map // Keep the error around, but clear the end time
mSyncErrorMap.remove(mid); syncError.holdEndTime = 0;
} }
} }
long freq = c.getInt(Mailbox.CONTENT_SYNC_INTERVAL_COLUMN); long freq = c.getInt(Mailbox.CONTENT_SYNC_INTERVAL_COLUMN);
@ -1512,6 +1527,7 @@ public class SyncManager extends Service implements Runnable {
static public void kick(String reason) { static public void kick(String reason) {
if (INSTANCE != null) { if (INSTANCE != null) {
synchronized (INSTANCE) { synchronized (INSTANCE) {
INSTANCE.mKicked = true;
INSTANCE.notify(); INSTANCE.notify();
} }
} }