Example #1
0
 private static void ShellEvents_DependencyRegistering(SchubertOptions option, DependencySetupEventArgs eventArgs)
 {
     //这里捞出要注册的服务。
     if (TryGetRemoteService(eventArgs.ActualDependency, option, out RemoteServiceAttribute remoteAttribute))
     {
         _serviceExports.Add(new SwiftyServiceDescriptor(eventArgs.ActualDependency.ServiceType, remoteAttribute.Version.IfNullOrWhiteSpace("1.0.0")));
     }
 }
Example #2
0
 //使用这个事件注册,确保之前的服务端已经注册,这样我们通过 TryAdd 语义排除掉已经注册的服务端接口。
 private static void ShellEvents_ShellInitialized(SchubertOptions options, Framework.Environment.ShellBuilders.ShellContext context)
 {
     if (_clientExports != null /*&& _clientExports.Count > 0*/)
     {
         context.RegisteredServices.AddSmart(_clientExports);
         context.RegisteredServices.AddSingleton <SwiftyClientManager, SwiftyClientManager>();
     }
 }
Example #3
0
        public ShellDescriptorManager(
            IRepository <ShellDescriptorRecord> repository,
            IOptions <SchubertOptions> options)
        {
            Guard.ArgumentNotNull(options, nameof(options));
            Guard.ArgumentNotNull(repository, nameof(repository));

            _repository = repository;
            _options    = options.Value;
        }
Example #4
0
        private static bool TryGetRemoteService(ServiceDescriptor serverTypeDesc, SchubertOptions options, out RemoteServiceAttribute attribute)
        {
            if (serverTypeDesc.ServiceType.TryGetRemoteServiceAttribute(true, out attribute))
            {
                if (!attribute.VipAddress.CaseInsensitiveEquals($"{options.Group}.{options.AppSystemName}"))
                {
                    var svcType = serverTypeDesc.ServiceType.GetTypeInfo();

                    String optionsName = nameof(SchubertOptions);
                    throw new SwiftyApplicationException($"{nameof(RemoteServiceAttribute)} 的属性" +
                                                         $" {nameof(RemoteServiceAttribute.VipAddress)} 必须使用 [{optionsName}.{nameof(SchubertOptions.Group)}].[{optionsName}.{nameof(SchubertOptions.AppSystemName)}] (区分大小写)格式。{System.Environment.NewLine}" +
                                                         $"类型 '{svcType.FullName}' 或程序集 '{svcType.Assembly.FullName}' 上的 {nameof(RemoteServiceAttribute)} 不满足该要求。");
                }

                return(true);
            }
            return(false);
        }
Example #5
0
        public ShellContextFactory(
            IShellDescriptorCache shellDescriptorCache,
            IShellDescriptorManager shellDescriptorManager,
            ICompositionStrategy compositionStrategy,
            IOptions <SchubertOptions> options,
            ILoggerFactory loggerFactory)
        {
            Guard.ArgumentNotNull(shellDescriptorManager, nameof(shellDescriptorManager));
            Guard.ArgumentNotNull(shellDescriptorCache, nameof(shellDescriptorCache));
            Guard.ArgumentNotNull(compositionStrategy, nameof(compositionStrategy));
            Guard.ArgumentNotNull(options, nameof(options));

            _options                = options.Value;
            _compositionStrategy    = compositionStrategy;
            _shellDescriptorManager = shellDescriptorManager;
            _shellDescriptorCache   = shellDescriptorCache;
            _logger = loggerFactory?.CreateLogger <ShellContextFactory>() ?? (ILogger)NullLogger.Instance;
        }
 private void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider obj)
 {
     this.Load();
 }
        private static void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider serviceProvider)
        {
            var schedulingServer = serviceProvider.GetRequiredService <ISchedulingServer>();

            schedulingServer.ScheduleAsync().GetAwaiter().GetResult();
        }
Example #8
0
        private static void ShellEvents_EngineStarted(SchubertOptions options, IServiceProvider serviceProvider)
        {
            ILoggerFactory loggerFactory = serviceProvider.GetRequiredService <ILoggerFactory>();
            ILogger        logger        = loggerFactory.CreateLogger("Schubert");

            //这里启动 Swifty 服务端。
            if (!(_serviceExports?.IsEmpty ?? true)) //其实不可能为空,防止手贱的反射该方法报错。
            {
                IOptions <SwiftyOptions>  swiftyOptions = serviceProvider.GetRequiredService <IOptions <SwiftyOptions> >();
                IOptions <NetworkOptions> netOptions    = serviceProvider.GetRequiredService <IOptions <NetworkOptions> >();

                /***************
                *
                * 地址是个棘手的问题
                *
                * 1、bindingAddress 为指定的 ip 地址:
                * 此时我们默认使用这个绑定地址即是他想要注册的地址。
                *
                * 2、考虑 bindingAddress 为空的情况:
                * 为空时候认为他要使用 network 配置,如果要使用 binding any 必须显式设置为 0.0.0.0
                * 因此,当 bindingAddress 为空时候我们就默认也注册 network 配置的地址
                *
                * 3、再来一种情况,考虑 bindingAddress 设置为  any(即 0.0.0.0) :
                * 这时候总不能向注册中心去注册 0.0.0.0 吧
                * 因此提供一个 public address 单独作为注册地址才能完整的解决问题
                * 考虑当 public address 为空,bind address 指定了 0.0.0.0:
                * 这种情况直接再读一次 network 配置,认为他要 bind 端口是本机所有网卡,但是只注册 network 的配置。
                *
                * 似乎没有什么逻辑漏洞,有的话 Swifty 里会再次为我们检查,详情见 swifty 实现。
                *
                ***************/

                if (swiftyOptions.Value.Server.BindingAddress.IsNullOrWhiteSpace())
                {
                    swiftyOptions.Value.Server.BindingAddress = GetNetworkAddress(netOptions);
                }
                var address = swiftyOptions.Value.Server.PublicAddress.IfNullOrWhiteSpace(swiftyOptions.Value.Server.BindingAddress);
                address = address.CaseSensitiveEquals("0.0.0.0") ? GetNetworkAddress(netOptions) : address;


                bool enableEureka = !String.IsNullOrWhiteSpace(swiftyOptions.Value.Server.Eureka.EurekaServerServiceUrls);

                if (address.IsNullOrWhiteSpace() && enableEureka)
                {
                    string optionProperty = $"{nameof(SwiftyOptions)}.{nameof(SwiftyOptions.Server)}.{nameof(ExtendedSwiftyServerOptions.PublicAddress)}";
                    string bindProperty   = $"{nameof(SwiftyOptions)}.{nameof(SwiftyOptions.Server)}.{nameof(ExtendedSwiftyServerOptions.BindingAddress)}";

                    string error = $"无法确定 Swifty 服务要发布的地址,考虑以下三种方式:{System.Environment.NewLine}" +
                                   $"1、请使用 '{nameof(NetworkOptions)}' 配置本机网络。{System.Environment.NewLine}" +
                                   $"2、使用 '{optionProperty}' 属性配置注册地址。{System.Environment.NewLine}" +
                                   $"3、通过'{bindProperty}' 属性指定明确的 TCP 绑定地址。{System.Environment.NewLine}";

                    throw new SchubertException(error);
                }
                InstanceDescription desc    = new InstanceDescription($"{options.AppSystemName}", $"{options.Group}.{options.AppSystemName}", address);
                IServiceLocator     locator = new SchubertServiceLocator(loggerFactory);

                SwiftyBootstrap boot = new SwiftyBootstrap(locator, swiftyOptions.Value.Server, desc, loggerFactory);

                var servies = _serviceExports.ToArray();
                //其实也清理不了什么,上一步的对象已经被引用了,清理一个 ConcurrentBag 结构吧。
                _serviceExports = null;

                boot
                .Handles(handlers => handlers.Add(new ScopeInjectionEventHandler()))
                .EurekaConfig(swiftyOptions.Value.Server.EnableEureka, swiftyOptions.Value.Server.Eureka)
                .AddServices(servies)
                .Bind(address, swiftyOptions.Value.Server.Port)
                .StartAsync().ContinueWith(s =>
                {
                    if (s.Exception != null)
                    {
                        logger.WriteError(0, "启动 swifty 服务器发生错误。", s.Exception);
                    }
                    else
                    {
                        logger.WriteInformation(0, $"swifty 服务器已经启动。{System.Environment.NewLine}" +
                                                $"(port: {s.Result.Port},  services: {servies.Length},  eureka: {enableEureka.ToString().ToLower()})。");
                    }
                });
            }
            else
            {
                logger.WriteWarning($"开启了 Swifty 服务端功能,但是没有发现可用的 Swifty 服务,是否在接口上遗漏了 {nameof(RemoteServiceAttribute)} 或 {nameof(ThriftServiceAttribute)}。");
            }
        }
Example #9
0
        private void ShellEvents_OnEngineStarted(SchubertOptions options, IServiceProvider serviceProvider)
        {
            var client = this.CreateOrGetZookeeperClient();

            this.LoadRemoteConfigurationAsync(client, true).GetAwaiter().GetResult();
        }