mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-15 15:26:31 +00:00
Convert update-lock.js to typescript
Change-type: patch
This commit is contained in:
parent
c1e24406d9
commit
596b316d65
@ -38,7 +38,8 @@ const availableDrives = require('./models/available-drives')
|
|||||||
const driveScanner = require('./modules/drive-scanner')
|
const driveScanner = require('./modules/drive-scanner')
|
||||||
const osDialog = require('./os/dialog')
|
const osDialog = require('./os/dialog')
|
||||||
const exceptionReporter = require('./modules/exception-reporter')
|
const exceptionReporter = require('./modules/exception-reporter')
|
||||||
const updateLock = require('./modules/update-lock')
|
// eslint-disable-next-line node/no-missing-require
|
||||||
|
const { updateLock } = require('./modules/update-lock')
|
||||||
|
|
||||||
/* eslint-disable lodash/prefer-lodash-method,lodash/prefer-get */
|
/* eslint-disable lodash/prefer-lodash-method,lodash/prefer-get */
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import * as flashState from '../../models/flash-state';
|
|||||||
import * as selectionState from '../../models/selection-state';
|
import * as selectionState from '../../models/selection-state';
|
||||||
import * as store from '../../models/store';
|
import * as store from '../../models/store';
|
||||||
import * as analytics from '../../modules/analytics';
|
import * as analytics from '../../modules/analytics';
|
||||||
import * as updateLock from '../../modules/update-lock';
|
import { updateLock } from '../../modules/update-lock';
|
||||||
import { open as openExternal } from '../../os/open-external/services/open-external';
|
import { open as openExternal } from '../../os/open-external/services/open-external';
|
||||||
import { FlashAnother } from '../flash-another/flash-another';
|
import { FlashAnother } from '../flash-another/flash-another';
|
||||||
import { FlashResults } from '../flash-results/flash-results';
|
import { FlashResults } from '../flash-results/flash-results';
|
||||||
|
@ -30,7 +30,8 @@ const permissions = require('../../../shared/permissions')
|
|||||||
// eslint-disable-next-line node/no-missing-require
|
// eslint-disable-next-line node/no-missing-require
|
||||||
const windowProgress = require('../os/window-progress')
|
const windowProgress = require('../os/window-progress')
|
||||||
const analytics = require('../modules/analytics')
|
const analytics = require('../modules/analytics')
|
||||||
const updateLock = require('./update-lock')
|
// eslint-disable-next-line node/no-missing-require
|
||||||
|
const { updateLock } = require('./update-lock')
|
||||||
const packageJSON = require('../../../../package.json')
|
const packageJSON = require('../../../../package.json')
|
||||||
const selectionState = require('../models/selection-state')
|
const selectionState = require('../models/selection-state')
|
||||||
|
|
||||||
|
@ -1,214 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2018 balena.io
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
const electron = require('electron')
|
|
||||||
const EventEmitter = require('events')
|
|
||||||
const createInactivityTimer = require('inactivity-timer')
|
|
||||||
const debug = require('debug')('etcher:update-lock')
|
|
||||||
const analytics = require('./analytics')
|
|
||||||
const settings = require('../models/settings')
|
|
||||||
|
|
||||||
/* eslint-disable no-magic-numbers, callback-return */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interaction timeout in milliseconds (defaults to 5 minutes)
|
|
||||||
* @type {Number}
|
|
||||||
* @constant
|
|
||||||
*/
|
|
||||||
const INTERACTION_TIMEOUT_MS = settings.has('interactionTimeout')
|
|
||||||
? parseInt(settings.get('interactionTimeout'), 10)
|
|
||||||
: 5 * 60 * 1000
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Balena Update Lock
|
|
||||||
* @class
|
|
||||||
*/
|
|
||||||
class UpdateLock extends EventEmitter {
|
|
||||||
/**
|
|
||||||
* @summary Balena Update Lock
|
|
||||||
* @example
|
|
||||||
* new UpdateLock()
|
|
||||||
*/
|
|
||||||
constructor () {
|
|
||||||
super()
|
|
||||||
this.paused = false
|
|
||||||
this.on('inactive', UpdateLock.onInactive)
|
|
||||||
this.lockTimer = createInactivityTimer(INTERACTION_TIMEOUT_MS, () => {
|
|
||||||
debug('inactive')
|
|
||||||
this.emit('inactive')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Inactivity event handler, releases the balena update lock on inactivity
|
|
||||||
* @private
|
|
||||||
* @example
|
|
||||||
* this.on('inactive', onInactive)
|
|
||||||
*/
|
|
||||||
static onInactive () {
|
|
||||||
if (settings.get('resinUpdateLock')) {
|
|
||||||
UpdateLock.check((checkError, isLocked) => {
|
|
||||||
debug('inactive-check', Boolean(checkError))
|
|
||||||
if (checkError) {
|
|
||||||
analytics.logException(checkError)
|
|
||||||
}
|
|
||||||
if (isLocked) {
|
|
||||||
UpdateLock.release((error) => {
|
|
||||||
debug('inactive-release', Boolean(error))
|
|
||||||
if (error) {
|
|
||||||
analytics.logException(error)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Acquire the update lock
|
|
||||||
* @private
|
|
||||||
* @param {Function} callback - callback(error)
|
|
||||||
* @example
|
|
||||||
* UpdateLock.acquire((error) => {
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
*/
|
|
||||||
static acquire (callback) {
|
|
||||||
debug('lock')
|
|
||||||
if (settings.get('resinUpdateLock')) {
|
|
||||||
electron.ipcRenderer.once('resin-update-lock', (event, error) => {
|
|
||||||
callback(error)
|
|
||||||
})
|
|
||||||
electron.ipcRenderer.send('resin-update-lock', 'lock')
|
|
||||||
} else {
|
|
||||||
callback(new Error('Update lock disabled'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Release the update lock
|
|
||||||
* @private
|
|
||||||
* @param {Function} callback - callback(error)
|
|
||||||
* @example
|
|
||||||
* UpdateLock.release((error) => {
|
|
||||||
* // ...
|
|
||||||
* })
|
|
||||||
*/
|
|
||||||
static release (callback) {
|
|
||||||
debug('unlock')
|
|
||||||
if (settings.get('resinUpdateLock')) {
|
|
||||||
electron.ipcRenderer.once('resin-update-lock', (event, error) => {
|
|
||||||
callback(error)
|
|
||||||
})
|
|
||||||
electron.ipcRenderer.send('resin-update-lock', 'unlock')
|
|
||||||
} else {
|
|
||||||
callback(new Error('Update lock disabled'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Check the state of the update lock
|
|
||||||
* @private
|
|
||||||
* @param {Function} callback - callback(error, isLocked)
|
|
||||||
* @example
|
|
||||||
* UpdateLock.check((error, isLocked) => {
|
|
||||||
* if (isLocked) {
|
|
||||||
* // ...
|
|
||||||
* }
|
|
||||||
* })
|
|
||||||
*/
|
|
||||||
static check (callback) {
|
|
||||||
debug('check')
|
|
||||||
if (settings.get('resinUpdateLock')) {
|
|
||||||
electron.ipcRenderer.once('resin-update-lock', (event, error, isLocked) => {
|
|
||||||
callback(error, isLocked)
|
|
||||||
})
|
|
||||||
electron.ipcRenderer.send('resin-update-lock', 'check')
|
|
||||||
} else {
|
|
||||||
callback(new Error('Update lock disabled'))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Extend the lock timer
|
|
||||||
* @example
|
|
||||||
* updateLock.extend()
|
|
||||||
*/
|
|
||||||
extend () {
|
|
||||||
debug('extend')
|
|
||||||
|
|
||||||
if (this.paused) {
|
|
||||||
debug('extend:paused')
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lockTimer.signal()
|
|
||||||
|
|
||||||
// When extending, check that we have the lock,
|
|
||||||
// and acquire it, if not
|
|
||||||
if (settings.get('resinUpdateLock')) {
|
|
||||||
UpdateLock.check((checkError, isLocked) => {
|
|
||||||
if (checkError) {
|
|
||||||
analytics.logException(checkError)
|
|
||||||
}
|
|
||||||
if (!isLocked) {
|
|
||||||
UpdateLock.acquire((error) => {
|
|
||||||
if (error) {
|
|
||||||
analytics.logException(error)
|
|
||||||
}
|
|
||||||
debug('extend-acquire', Boolean(error))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Clear the lock timer
|
|
||||||
* @example
|
|
||||||
* updateLock.clearTimer()
|
|
||||||
*/
|
|
||||||
clearTimer () {
|
|
||||||
debug('clear')
|
|
||||||
this.lockTimer.clear()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Clear the lock timer, and pause extension, avoiding triggering until resume()d
|
|
||||||
* @example
|
|
||||||
* updateLock.pause()
|
|
||||||
*/
|
|
||||||
pause () {
|
|
||||||
debug('pause')
|
|
||||||
this.paused = true
|
|
||||||
this.clearTimer()
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Un-pause lock extension, and restart the timer
|
|
||||||
* @example
|
|
||||||
* updateLock.resume()
|
|
||||||
*/
|
|
||||||
resume () {
|
|
||||||
debug('resume')
|
|
||||||
this.paused = false
|
|
||||||
this.extend()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = new UpdateLock()
|
|
188
lib/gui/app/modules/update-lock.ts
Normal file
188
lib/gui/app/modules/update-lock.ts
Normal file
@ -0,0 +1,188 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2018 balena.io
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import * as _debug from 'debug';
|
||||||
|
import * as electron from 'electron';
|
||||||
|
import { EventEmitter } from 'events';
|
||||||
|
import * as createInactivityTimer from 'inactivity-timer';
|
||||||
|
|
||||||
|
import * as settings from '../models/settings';
|
||||||
|
import { logException } from './analytics';
|
||||||
|
|
||||||
|
const debug = _debug('etcher:update-lock');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interaction timeout in milliseconds (defaults to 5 minutes)
|
||||||
|
* @type {Number}
|
||||||
|
* @constant
|
||||||
|
*/
|
||||||
|
const INTERACTION_TIMEOUT_MS = settings.has('interactionTimeout')
|
||||||
|
? parseInt(settings.get('interactionTimeout'), 10)
|
||||||
|
: 5 * 60 * 1000;
|
||||||
|
|
||||||
|
class UpdateLock extends EventEmitter {
|
||||||
|
private paused: boolean;
|
||||||
|
private lockTimer: any;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.paused = false;
|
||||||
|
this.on('inactive', UpdateLock.onInactive);
|
||||||
|
this.lockTimer = createInactivityTimer(INTERACTION_TIMEOUT_MS, () => {
|
||||||
|
debug('inactive');
|
||||||
|
this.emit('inactive');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Inactivity event handler, releases the balena update lock on inactivity
|
||||||
|
*/
|
||||||
|
private static onInactive() {
|
||||||
|
if (settings.get('resinUpdateLock')) {
|
||||||
|
UpdateLock.check((checkError: Error, isLocked: boolean) => {
|
||||||
|
debug('inactive-check', Boolean(checkError));
|
||||||
|
if (checkError) {
|
||||||
|
logException(checkError);
|
||||||
|
}
|
||||||
|
if (isLocked) {
|
||||||
|
UpdateLock.release((error?: Error) => {
|
||||||
|
debug('inactive-release', Boolean(error));
|
||||||
|
if (error) {
|
||||||
|
logException(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Acquire the update lock
|
||||||
|
*/
|
||||||
|
private static acquire(callback: (error?: Error) => void) {
|
||||||
|
debug('lock');
|
||||||
|
if (settings.get('resinUpdateLock')) {
|
||||||
|
electron.ipcRenderer.once('resin-update-lock', (_event, error) => {
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
electron.ipcRenderer.send('resin-update-lock', 'lock');
|
||||||
|
} else {
|
||||||
|
callback(new Error('Update lock disabled'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Release the update lock
|
||||||
|
*/
|
||||||
|
public static release(callback: (error?: Error) => void) {
|
||||||
|
debug('unlock');
|
||||||
|
if (settings.get('resinUpdateLock')) {
|
||||||
|
electron.ipcRenderer.once('resin-update-lock', (_event, error) => {
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
electron.ipcRenderer.send('resin-update-lock', 'unlock');
|
||||||
|
} else {
|
||||||
|
callback(new Error('Update lock disabled'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Check the state of the update lock
|
||||||
|
* @param {Function} callback - callback(error, isLocked)
|
||||||
|
* @example
|
||||||
|
* UpdateLock.check((error, isLocked) => {
|
||||||
|
* if (isLocked) {
|
||||||
|
* // ...
|
||||||
|
* }
|
||||||
|
* })
|
||||||
|
*/
|
||||||
|
private static check(
|
||||||
|
callback: (error: Error | null, isLocked?: boolean) => void,
|
||||||
|
) {
|
||||||
|
debug('check');
|
||||||
|
if (settings.get('resinUpdateLock')) {
|
||||||
|
electron.ipcRenderer.once(
|
||||||
|
'resin-update-lock',
|
||||||
|
(_event, error, isLocked) => {
|
||||||
|
callback(error, isLocked);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
electron.ipcRenderer.send('resin-update-lock', 'check');
|
||||||
|
} else {
|
||||||
|
callback(new Error('Update lock disabled'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Extend the lock timer
|
||||||
|
*/
|
||||||
|
public extend() {
|
||||||
|
debug('extend');
|
||||||
|
|
||||||
|
if (this.paused) {
|
||||||
|
debug('extend:paused');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.lockTimer.signal();
|
||||||
|
|
||||||
|
// When extending, check that we have the lock,
|
||||||
|
// and acquire it, if not
|
||||||
|
if (settings.get('resinUpdateLock')) {
|
||||||
|
UpdateLock.check((checkError, isLocked) => {
|
||||||
|
if (checkError) {
|
||||||
|
logException(checkError);
|
||||||
|
}
|
||||||
|
if (!isLocked) {
|
||||||
|
UpdateLock.acquire(error => {
|
||||||
|
if (error) {
|
||||||
|
logException(error);
|
||||||
|
}
|
||||||
|
debug('extend-acquire', Boolean(error));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Clear the lock timer
|
||||||
|
*/
|
||||||
|
private clearTimer() {
|
||||||
|
debug('clear');
|
||||||
|
this.lockTimer.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Clear the lock timer, and pause extension, avoiding triggering until resume()d
|
||||||
|
*/
|
||||||
|
public pause() {
|
||||||
|
debug('pause');
|
||||||
|
this.paused = true;
|
||||||
|
this.clearTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Un-pause lock extension, and restart the timer
|
||||||
|
*/
|
||||||
|
public resume() {
|
||||||
|
debug('resume');
|
||||||
|
this.paused = false;
|
||||||
|
this.extend();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const updateLock = new UpdateLock();
|
Loading…
x
Reference in New Issue
Block a user