src/index.js
async function _shutdownNextServices(reversedServiceSequence) {
          if (0 === reversedServiceSequence.length) {
            return;
          }

          await Promise.all(
            reversedServiceSequence.pop().map(async serviceName => {
              const singletonServiceDescriptor = await _this._pickupSingletonServiceDescriptorPromise(
                serviceName,
              );
              const serviceDescriptor =
                singletonServiceDescriptor ||
                (await siloContext.servicesDescriptors.get(serviceName));
              let serviceShutdownPromise =
                _this._singletonsServicesShutdownsPromises.get(serviceName) ||
                siloContext.servicesShutdownsPromises.get(serviceName);

              if (serviceShutdownPromise) {
                debug('Reusing a service shutdown promise:', serviceName);
                return serviceShutdownPromise;
              }

              if (
                reversedServiceSequence.some(servicesDeclarations =>
                  servicesDeclarations.includes(serviceName),
                )
              ) {
                debug('Delaying service shutdown:', serviceName);
                return Promise.resolve();
              }
              if (singletonServiceDescriptor) {
                const handleSet = _this._singletonsServicesHandles.get(
                  serviceName,
                );

                handleSet.delete(siloContext.name);
                if (handleSet.size) {
                  debug('Singleton is used elsewhere:', serviceName, handleSet);
                  return Promise.resolve();
                }
                _this._singletonsServicesDescriptors.delete(serviceName);
              }
              debug('Shutting down a service:', serviceName);
              serviceShutdownPromise = serviceDescriptor.dispose
                ? serviceDescriptor.dispose()
                : Promise.resolve();
              if (singletonServiceDescriptor) {
                _this._singletonsServicesShutdownsPromises.set(
                  serviceName,
                  serviceShutdownPromise,
                );
              }
              siloContext.servicesShutdownsPromises.set(
                serviceName,
                serviceShutdownPromise,
              );
              return serviceShutdownPromise;
            }),
          );

          await _shutdownNextServices(reversedServiceSequence);
        }
async function _shutdownNextServices(reversedServiceSequence) {
          if (0 === reversedServiceSequence.length) {
            return;
          }

          await Promise.all(
            reversedServiceSequence.pop().map(async serviceName => {
              const singletonServiceDescriptor = await _this._pickupSingletonServiceDescriptorPromise(
                serviceName,
              );
              const serviceDescriptor =
                singletonServiceDescriptor ||
                (await siloContext.servicesDescriptors.get(serviceName));
              let serviceShutdownPromise =
                _this._singletonsServicesShutdownsPromises.get(serviceName) ||
                siloContext.servicesShutdownsPromises.get(serviceName);

              if (serviceShutdownPromise) {
                debug('Reusing a service shutdown promise:', serviceName);
                return serviceShutdownPromise;
              }

              if (
                reversedServiceSequence.some(servicesDeclarations =>
                  servicesDeclarations.includes(serviceName),
                )
              ) {
                debug('Delaying service shutdown:', serviceName);
                return Promise.resolve();
              }
              if (singletonServiceDescriptor) {
                const handleSet = _this._singletonsServicesHandles.get(
                  serviceName,
                );

                handleSet.delete(siloContext.name);
                if (handleSet.size) {
                  debug('Singleton is used elsewhere:', serviceName, handleSet);
                  return Promise.resolve();
                }
                _this._singletonsServicesDescriptors.delete(serviceName);
              }
              debug('Shutting down a service:', serviceName);
              serviceShutdownPromise = serviceDescriptor.dispose
                ? serviceDescriptor.dispose()
                : Promise.resolve();
              if (singletonServiceDescriptor) {
                _this._singletonsServicesShutdownsPromises.set(
                  serviceName,
                  serviceShutdownPromise,
                );
              }
              siloContext.servicesShutdownsPromises.set(
                serviceName,
                serviceShutdownPromise,
              );
              return serviceShutdownPromise;
            }),
          );

          await _shutdownNextServices(reversedServiceSequence);
        }
async function _shutdownNextServices ( reversedServiceSequence ) { if ( 0 === reversedServiceSequence . length ) { return ; } await Promise . all ( reversedServiceSequence . pop ( ) . map ( async serviceName => { const singletonServiceDescriptor = await _this . _pickupSingletonServiceDescriptorPromise ( serviceName , ) ; const serviceDescriptor = singletonServiceDescriptor || ( await siloContext . servicesDescriptors . get ( serviceName ) ) ; let serviceShutdownPromise = _this . _singletonsServicesShutdownsPromises . get ( serviceName ) || siloContext . servicesShutdownsPromises . get ( serviceName ) ; if ( serviceShutdownPromise ) { debug ( 'Reusing a service shutdown promise:' , serviceName ) ; return serviceShutdownPromise ; } if ( reversedServiceSequence . some ( servicesDeclarations => servicesDeclarations . includes ( serviceName ) , ) ) { debug ( 'Delaying service shutdown:' , serviceName ) ; return Promise . resolve ( ) ; } if ( singletonServiceDescriptor ) { const handleSet = _this . _singletonsServicesHandles . get ( serviceName , ) ; handleSet . delete ( siloContext . name ) ; if ( handleSet . size ) { debug ( 'Singleton is used elsewhere:' , serviceName , handleSet ) ; return Promise . resolve ( ) ; } _this . _singletonsServicesDescriptors . delete ( serviceName ) ; } debug ( 'Shutting down a service:' , serviceName ) ; serviceShutdownPromise = serviceDescriptor . dispose ? serviceDescriptor . dispose ( ) : Promise . resolve ( ) ; if ( singletonServiceDescriptor ) { _this . _singletonsServicesShutdownsPromises . set ( serviceName , serviceShutdownPromise , ) ; } siloContext . servicesShutdownsPromises . set ( serviceName , serviceShutdownPromise , ) ; return serviceShutdownPromise ; } ) , ) ; await _shutdownNextServices ( reversedServiceSequence ) ; }
Shutdown services in their instanciation order
Shutdown services in their instanciation order