Add retries around android device watching
Summary: Retry up to 5 times with exponential backoff. Reviewed By: passy Differential Revision: D13138244 fbshipit-source-id: 94c68b87aa281cfc3239b0bb8bdd75a2e0d7edc7
This commit is contained in:
committed by
Facebook Github Bot
parent
9e6a86923a
commit
ca1f0202d7
@@ -7,6 +7,7 @@
|
||||
|
||||
import AndroidDevice from '../devices/AndroidDevice';
|
||||
import child_process from 'child_process';
|
||||
import promiseRetry from 'promise-retry';
|
||||
import type {Store} from '../reducers/index.js';
|
||||
import type BaseDevice from '../devices/BaseDevice';
|
||||
import type Logger from '../fb-stubs/Logger.js';
|
||||
@@ -57,10 +58,28 @@ export default (store: Store, logger: Logger) => {
|
||||
// Using this client before adb server is started up will cause failures.
|
||||
// this gets around this by waiting for listDevices first, which ensures
|
||||
// the server is up and running before allowing any other operations.
|
||||
const clientPromise = (() => {
|
||||
|
||||
function createClient() {
|
||||
const unsafeClient = adb.createClient();
|
||||
return unsafeClient.listDevices().then(() => unsafeClient);
|
||||
})();
|
||||
return promiseRetry(
|
||||
(retry, number) => {
|
||||
return unsafeClient
|
||||
.listDevices()
|
||||
.then(() => {
|
||||
return unsafeClient;
|
||||
})
|
||||
.catch(e => {
|
||||
console.warn(`Failed to start adb client. Retrying. ${e.message}`);
|
||||
retry(e);
|
||||
});
|
||||
},
|
||||
{
|
||||
minTimeout: 200,
|
||||
retries: 5,
|
||||
},
|
||||
);
|
||||
}
|
||||
const clientPromise = createClient();
|
||||
|
||||
const watchAndroidDevices = () => {
|
||||
// get emulators
|
||||
@@ -79,71 +98,77 @@ export default (store: Store, logger: Logger) => {
|
||||
},
|
||||
);
|
||||
|
||||
clientPromise.then(client => {
|
||||
client
|
||||
.trackDevices()
|
||||
.then(tracker => {
|
||||
tracker.on('error', err => {
|
||||
if (err.message === 'Connection closed') {
|
||||
// adb server has shutdown, remove all android devices
|
||||
const {connections} = store.getState();
|
||||
const deviceIDsToRemove: Array<
|
||||
string,
|
||||
> = connections.devices
|
||||
.filter((device: BaseDevice) => device instanceof AndroidDevice)
|
||||
.map((device: BaseDevice) => device.serial);
|
||||
clientPromise
|
||||
.then(client => {
|
||||
client
|
||||
.trackDevices()
|
||||
.then(tracker => {
|
||||
tracker.on('error', err => {
|
||||
if (err.message === 'Connection closed') {
|
||||
// adb server has shutdown, remove all android devices
|
||||
const {connections} = store.getState();
|
||||
const deviceIDsToRemove: Array<
|
||||
string,
|
||||
> = connections.devices
|
||||
.filter(
|
||||
(device: BaseDevice) => device instanceof AndroidDevice,
|
||||
)
|
||||
.map((device: BaseDevice) => device.serial);
|
||||
|
||||
store.dispatch({
|
||||
type: 'UNREGISTER_DEVICES',
|
||||
payload: new Set(deviceIDsToRemove),
|
||||
});
|
||||
console.error('adb server was shutdown');
|
||||
setTimeout(watchAndroidDevices, 500);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
store.dispatch({
|
||||
type: 'UNREGISTER_DEVICES',
|
||||
payload: new Set(deviceIDsToRemove),
|
||||
});
|
||||
console.error('adb server was shutdown');
|
||||
setTimeout(watchAndroidDevices, 500);
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
tracker.on('add', async device => {
|
||||
if (device.type !== 'offline') {
|
||||
const androidDevice = await createDevice(client, device);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: androidDevice,
|
||||
});
|
||||
}
|
||||
});
|
||||
tracker.on('add', async device => {
|
||||
if (device.type !== 'offline') {
|
||||
const androidDevice = await createDevice(client, device);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: androidDevice,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
tracker.on('change', async device => {
|
||||
if (device.type === 'offline') {
|
||||
tracker.on('change', async device => {
|
||||
if (device.type === 'offline') {
|
||||
store.dispatch({
|
||||
type: 'UNREGISTER_DEVICES',
|
||||
payload: new Set([device.id]),
|
||||
});
|
||||
} else {
|
||||
const androidDevice = await createDevice(client, device);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: androidDevice,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
tracker.on('remove', device => {
|
||||
store.dispatch({
|
||||
type: 'UNREGISTER_DEVICES',
|
||||
payload: new Set([device.id]),
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.code === 'ECONNREFUSED') {
|
||||
// adb server isn't running
|
||||
} else {
|
||||
const androidDevice = await createDevice(client, device);
|
||||
store.dispatch({
|
||||
type: 'REGISTER_DEVICE',
|
||||
payload: androidDevice,
|
||||
});
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
|
||||
tracker.on('remove', device => {
|
||||
store.dispatch({
|
||||
type: 'UNREGISTER_DEVICES',
|
||||
payload: new Set([device.id]),
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.code === 'ECONNREFUSED') {
|
||||
// adb server isn't running
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
});
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
console.error(`Failed to watch for android devices: ${e.message}`);
|
||||
});
|
||||
};
|
||||
|
||||
watchAndroidDevices();
|
||||
|
||||
Reference in New Issue
Block a user