Browse Source

refactor(device): 优化安装APK流程

- 添加AsyncLock库以确保APK更新过程中的同步性
- 优化安装APK的调度逻辑,每2分钟执行一次
- 修复了在更新APK时可能出现的错误
xiongzhu 1 year ago
parent
commit
fb166c21db
1 changed files with 39 additions and 23 deletions
  1. 39 23
      src/device/device.service.ts

+ 39 - 23
src/device/device.service.ts

@@ -26,10 +26,12 @@ import { randomUUID } from 'crypto'
 import { setTimeout } from 'timers/promises'
 import { setTimeout } from 'timers/promises'
 import { SendMessageDto } from './dtos/send-message.dto'
 import { SendMessageDto } from './dtos/send-message.dto'
 import { SysConfigService } from 'src/sys-config/sys-config.service'
 import { SysConfigService } from 'src/sys-config/sys-config.service'
+import * as AsyncLock from 'async-lock'
 
 
 @Injectable()
 @Injectable()
 export class DeviceService implements OnModuleInit {
 export class DeviceService implements OnModuleInit {
     private ipmoyuProvider: ProxyProvider = new IpmoyuProvider()
     private ipmoyuProvider: ProxyProvider = new IpmoyuProvider()
+    private lock = new AsyncLock()
     constructor(
     constructor(
         @InjectRepository(Device)
         @InjectRepository(Device)
         private deviceRepository: Repository<Device>,
         private deviceRepository: Repository<Device>,
@@ -374,30 +376,44 @@ export class DeviceService implements OnModuleInit {
         )
         )
     }
     }
 
 
-    @Interval(5 * 60 * 1000)
+    @Interval(2 * 60 * 1000)
     async scheduleApkUpdate() {
     async scheduleApkUpdate() {
-        const apkUrl = await this.sysConfigService.getString('modifier_apk', '')
-        if (!apkUrl) return
-        const apkVersion = await this.sysConfigService.getNumber('modifier_apk_version', 0)
-        if (!apkVersion) return
-        const devices = await this.deviceRepository.findBy({
-            online: true,
-            busy: false
-        })
-        for (const device of devices) {
-            if (!device.version || Number(device.version) < apkVersion) {
-                this.eventsGateway.send(
-                    {
-                        id: randomUUID(),
-                        action: 'installApk',
-                        data: {
-                            apkUrl: apkUrl
+        this.lock
+            .acquire(
+                'apkUpdate',
+                async () => {
+                    const apkUrl = await this.sysConfigService.getString('modifier_apk', '')
+                    if (!apkUrl) return
+                    const apkVersion = await this.sysConfigService.getNumber('modifier_apk_version', 0)
+                    if (!apkVersion) return
+                    const devices = await this.deviceRepository.findBy({
+                        online: true,
+                        busy: false
+                    })
+                    for (const device of devices) {
+                        if (!device.version || Number(device.version) < apkVersion) {
+                            try {
+                                this.eventsGateway.send(
+                                    {
+                                        id: randomUUID(),
+                                        action: 'installApk',
+                                        data: {
+                                            apkUrl: apkUrl
+                                        }
+                                    },
+                                    device.socketId
+                                )
+                            } catch (e) {
+                                Logger.error('Error updating apk', 'device')
+                            }
                         }
                         }
-                    },
-                    device.socketId
-                )
-            }
-            await setTimeout(1000)
-        }
+                        await setTimeout(1000)
+                    }
+                },
+                { timeout: 1 }
+            )
+            .catch((e) => {
+                Logger.error('Error updating apk, already updating', 'device')
+            })
     }
     }
 }
 }