diff --git a/server/python/rpc.py b/server/python/rpc.py index 44c9c3590..65ab84999 100644 --- a/server/python/rpc.py +++ b/server/python/rpc.py @@ -309,7 +309,7 @@ class RpcPeer: result['result'] = self.serialize(value, False) except Exception as e: tb = traceback.format_exc() - print('failure', method, e, tb) + # print('failure', method, e, tb) self.createErrorResult( result, type(e).__name__, str(e), tb) diff --git a/server/src/rpc.ts b/server/src/rpc.ts index fbb6bc6fb..8f02bcea4 100644 --- a/server/src/rpc.ts +++ b/server/src/rpc.ts @@ -508,7 +508,7 @@ export class RpcPeer { result.result = this.serialize(value); } catch (e) { - console.error('failure', rpcApply.method, e); + // console.error('failure', rpcApply.method, e); this.createErrorResult(result, e); } diff --git a/server/src/runtime.ts b/server/src/runtime.ts index 17e2f6940..5d53c1d8a 100644 --- a/server/src/runtime.ts +++ b/server/src/runtime.ts @@ -390,7 +390,7 @@ export class ScryptedRuntime extends PluginHttp { const remaining = [...ids]; // first pass: - // for every id, find anything it is acting as a mixin, and clear out the entry. + // for every id, find anything it is acting on as a mixin, and clear out the entry. while (remaining.length) { const id = remaining.pop(); @@ -594,7 +594,7 @@ export class ScryptedRuntime extends PluginHttp { } async removeDevice(device: PluginDevice) { - const providerId = getState(device, ScryptedInterfaceProperty.providerId); + // delete any devices provided by this device const providedDevices = Object.values(this.pluginDevices).filter(pluginDevice => getState(pluginDevice, ScryptedInterfaceProperty.providerId) === device._id); for (const provided of providedDevices) { if (provided === device) @@ -606,22 +606,22 @@ export class ScryptedRuntime extends PluginHttp { this.invalidatePluginDevice(device._id); delete this.pluginDevices[device._id]; await this.datastore.remove(device); - if (providerId == null || providerId === device._id) { - const plugin = await this.datastore.tryGet(Plugin, device.pluginId); - this.killPlugin(plugin._id); - await this.datastore.remove(plugin); - rimraf.sync(getPluginVolume(plugin._id)); - } this.stateManager.removeDevice(device._id); - const plugin = this.plugins[device.pluginId]; - // remove the plugin too + // if this device is acting as a mixin on anything, can now remove invalidate it. + // when the mixin table is rebuilt, it will be automatically ignore and remove the dangling mixin. + this.invalidateMixins(new Set([device._id])); + + // if the device is a plugin, kill and remove the plugin as well. if (!device.nativeId) { - plugin?.kill(); + this.killPlugin(device.pluginId); await this.datastore.removeId(Plugin, device.pluginId); + rimraf.sync(getPluginVolume(device.pluginId)); } else { try { + // notify the plugin that a device was removed. + const plugin = this.plugins[device.pluginId]; await plugin.remote.setNativeId(device.nativeId, undefined, undefined); } catch (e) {