diff --git a/__tests__/ut/commands/deploy/impl/function_test.ts b/__tests__/ut/commands/deploy/impl/function_test.ts index d3830585..cb14a8de 100644 --- a/__tests__/ut/commands/deploy/impl/function_test.ts +++ b/__tests__/ut/commands/deploy/impl/function_test.ts @@ -378,6 +378,98 @@ describe('Service', () => { }, ); }); + + it('should set idleTimeout to -1 when it is not configured', async () => { + service = new Service(mockInputs, mockOpts); + service.needDeploy = true; + Object.defineProperty(service, 'type', { + value: 'config', + writable: true, + }); + + const mockFcSdk = { + deployFunction: jest.fn().mockResolvedValue(undefined), + }; + Object.defineProperty(service, 'fcSdk', { + value: mockFcSdk, + writable: true, + }); + + jest.spyOn(service as any, '_deployAuto').mockResolvedValue(undefined); + + await service.run(); + + expect(service.fcSdk.deployFunction).toHaveBeenCalledWith( + expect.objectContaining({ + idleTimeout: -1, + }), + expect.anything(), + ); + }); + + it('should convert idleTimeout 0 or null to -1', async () => { + for (const idleTimeout of [0, null]) { + service = new Service( + { ...mockInputs, props: { ...mockInputs.props, idleTimeout } } as any, + mockOpts, + ); + service.needDeploy = true; + Object.defineProperty(service, 'type', { + value: 'config', + writable: true, + }); + + const mockFcSdk = { + deployFunction: jest.fn().mockResolvedValue(undefined), + }; + Object.defineProperty(service, 'fcSdk', { + value: mockFcSdk, + writable: true, + }); + + jest.spyOn(service as any, '_deployAuto').mockResolvedValue(undefined); + + await service.run(); + + expect(service.fcSdk.deployFunction).toHaveBeenCalledWith( + expect.objectContaining({ + idleTimeout: -1, + }), + expect.anything(), + ); + } + }); + + it('should keep configured idleTimeout', async () => { + service = new Service( + { ...mockInputs, props: { ...mockInputs.props, idleTimeout: 600 } } as any, + mockOpts, + ); + service.needDeploy = true; + Object.defineProperty(service, 'type', { + value: 'config', + writable: true, + }); + + const mockFcSdk = { + deployFunction: jest.fn().mockResolvedValue(undefined), + }; + Object.defineProperty(service, 'fcSdk', { + value: mockFcSdk, + writable: true, + }); + + jest.spyOn(service as any, '_deployAuto').mockResolvedValue(undefined); + + await service.run(); + + expect(service.fcSdk.deployFunction).toHaveBeenCalledWith( + expect.objectContaining({ + idleTimeout: 600, + }), + expect.anything(), + ); + }); }); describe('_getAcr', () => { diff --git a/publish.yaml b/publish.yaml index 643e2a98..65cb28f1 100644 --- a/publish.yaml +++ b/publish.yaml @@ -3,7 +3,7 @@ Type: Component Name: fc3 Provider: - 阿里云 -Version: 0.1.25 +Version: 0.1.27 Description: 阿里云函数计算全生命周期管理 HomePage: https://github.com/devsapp/fc3 Organization: 阿里云函数计算(FC) diff --git a/src/default/config.ts b/src/default/config.ts index f8ef3d9d..1936d102 100644 --- a/src/default/config.ts +++ b/src/default/config.ts @@ -42,6 +42,8 @@ export const FC_RESOURCES_EMPTY_CONFIG = { layers: [], instanceIsolationMode: 'SHARE', sessionAffinity: 'NONE', + // 服务端不支持通过省略该字段或置 0 清除线上值,-1 表示关闭延时释放弹性实例 + idleTimeout: -1, }; export const FC_TRIGGER_DEFAULT_CONFIG = { diff --git a/src/subCommands/deploy/impl/function.ts b/src/subCommands/deploy/impl/function.ts index 51821cb4..ddb40e60 100644 --- a/src/subCommands/deploy/impl/function.ts +++ b/src/subCommands/deploy/impl/function.ts @@ -124,6 +124,11 @@ export default class Service extends Base { } // 部署函数 const config = _.defaults(this.local, FC_RESOURCES_EMPTY_CONFIG); + // idleTimeout 0 / null 均非法(服务端最小 300 且不支持空值清除),与未配置一致按关闭处理 + if (config.idleTimeout === 0 || config.idleTimeout === null) { + logger.debug('idleTimeout 0/null is converted to -1 (disabled)'); + config.idleTimeout = -1; + } if ( !_.isEmpty(config.sessionAffinityConfig) && typeof config.sessionAffinityConfig !== 'string'