Example #1
0
        public RepositoryHosts(
            IRepositoryHostFactory repositoryHostFactory,
            ISharedCache sharedCache,
            IConnectionManager connectionManager)
        {
            this.connectionManager = connectionManager;

            RepositoryHostFactory = repositoryHostFactory;
            GitHubHost            = DisconnectedRepositoryHost;
            EnterpriseHost        = DisconnectedRepositoryHost;

            var initialCacheLoadObs = sharedCache.UserAccount.GetObject <Uri>(EnterpriseHostApiBaseUriCacheKey)
                                      .Catch <Uri, KeyNotFoundException>(_ => Observable.Return <Uri>(null))
                                      .Catch <Uri, Exception>(ex =>
            {
                log.Warn("Failed to get Enterprise host URI from cache.", ex);
                return(Observable.Return <Uri>(null));
            })
                                      .WhereNotNull()
                                      .Select(HostAddress.Create)
                                      .Where(x => connectionManager.Connections.Any(c => c.HostAddress.Equals(x)))
                                      .Select(repositoryHostFactory.Create)
                                      .Do(x => EnterpriseHost = x)
                                      .Do(disposables.Add)
                                      .SelectUnit();

            var persistEntepriseHostObs = this.WhenAny(x => x.EnterpriseHost, x => x.Value)
                                          .Skip(1) // The first value will be null or something already in the db
                                          .SelectMany(enterpriseHost =>
            {
                if (!enterpriseHost.IsLoggedIn)
                {
                    return(sharedCache.UserAccount
                           .InvalidateObject <Uri>(EnterpriseHostApiBaseUriCacheKey)
                           .Catch <Unit, Exception>(ex =>
                    {
                        log.Warn("Failed to invalidate enterprise host uri", ex);
                        return Observable.Return(Unit.Default);
                    }));
                }

                return(sharedCache.UserAccount
                       .InsertObject(EnterpriseHostApiBaseUriCacheKey, enterpriseHost.Address.ApiUri)
                       .Catch <Unit, Exception>(ex =>
                {
                    log.Warn("Failed to persist enterprise host uri", ex);
                    return Observable.Return(Unit.Default);
                }));
            });

            isLoggedInToAnyHost = this.WhenAny(
                x => x.GitHubHost.IsLoggedIn,
                x => x.EnterpriseHost.IsLoggedIn,
                (githubLoggedIn, enterpriseLoggedIn) => githubLoggedIn.Value || enterpriseLoggedIn.Value)
                                  .ToProperty(this, x => x.IsLoggedInToAnyHost);

            // This part is strictly to support having the IConnectionManager request that a connection
            // be logged in. It doesn't know about hosts or load anything reactive, so it gets
            // informed of logins by an observable returned by the event
            connectionManager.DoLogin += RunLoginHandler;

            // monitor the list of connections so we can log out hosts when connections are removed
            disposables.Add(
                connectionManager.Connections.CreateDerivedCollection(x => x)
                .ItemsRemoved
                .Select(x =>
            {
                var host = LookupHost(x.HostAddress);
                if (host.Address != x.HostAddress)
                {
                    host = RepositoryHostFactory.Create(x.HostAddress);
                }
                return(host);
            })
                .Select(h => LogOut(h))
                .Merge().ToList().Select(_ => Unit.Default).Subscribe());


            // Wait until we've loaded (or failed to load) an enterprise uri from the db and then
            // start tracking changes to the EnterpriseHost property and persist every change to the db
            disposables.Add(Observable.Concat(initialCacheLoadObs, persistEntepriseHostObs).Subscribe());
        }
        public RepositoryHosts(
            IRepositoryHostFactory repositoryHostFactory,
            ISharedCache sharedCache,
            IConnectionManager connectionManager)
        {
            this.connectionManager = connectionManager;

            RepositoryHostFactory = repositoryHostFactory;
            disposables.Add(repositoryHostFactory);
            GitHubHost = DisconnectedRepositoryHost;
            EnterpriseHost = DisconnectedRepositoryHost;

            var initialCacheLoadObs = sharedCache.UserAccount.GetObject<Uri>(EnterpriseHostApiBaseUriCacheKey)
                .Catch<Uri, KeyNotFoundException>(_ => Observable.Return<Uri>(null))
                .Catch<Uri, Exception>(ex =>
                {
                    log.Warn("Failed to get Enterprise host URI from cache.", ex);
                    return Observable.Return<Uri>(null);
                })
                .WhereNotNull()
                .Select(HostAddress.Create)
                .Where(x => connectionManager.Connections.Any(c => c.HostAddress.Equals(x)))
                .Select(repositoryHostFactory.Create)
                .Do(x => EnterpriseHost = x)
                .Do(disposables.Add)
                .SelectUnit();

            var persistEntepriseHostObs = this.WhenAny(x => x.EnterpriseHost, x => x.Value)
                .Skip(1)  // The first value will be null or something already in the db
                .SelectMany(enterpriseHost =>
                {
                    if (!enterpriseHost.IsLoggedIn)
                    {
                        return sharedCache.UserAccount
                            .InvalidateObject<Uri>(EnterpriseHostApiBaseUriCacheKey)
                            .Catch<Unit, Exception>(ex =>
                            {
                                log.Warn("Failed to invalidate enterprise host uri", ex);
                                return Observable.Return(Unit.Default);
                            });
                    }

                    return sharedCache.UserAccount
                        .InsertObject(EnterpriseHostApiBaseUriCacheKey, enterpriseHost.Address.ApiUri)
                        .Catch<Unit, Exception>(ex =>
                        {
                            log.Warn("Failed to persist enterprise host uri", ex);
                            return Observable.Return(Unit.Default);
                        });
                });

            isLoggedInToAnyHost = this.WhenAny(
                x => x.GitHubHost.IsLoggedIn,
                x => x.EnterpriseHost.IsLoggedIn,
                (githubLoggedIn, enterpriseLoggedIn) => githubLoggedIn.Value || enterpriseLoggedIn.Value)
                .ToProperty(this, x => x.IsLoggedInToAnyHost);

            // This part is strictly to support having the IConnectionManager request that a connection
            // be logged in. It doesn't know about hosts or load anything reactive, so it gets
            // informed of logins by an observable returned by the event
            connectionManager.DoLogin += RunLoginHandler;

            // monitor the list of connections so we can log out hosts when connections are removed
            disposables.Add(
                connectionManager.Connections.CreateDerivedCollection(x => x)
                .ItemsRemoved
                .Select(x =>
                {
                    var host = LookupHost(x.HostAddress);
                    if (host.Address != x.HostAddress)
                    {
                        host = RepositoryHostFactory.Create(x.HostAddress);
                    }
                    return host;
                })
                .Select(h => LogOut(h))
                .Merge().ToList().Select(_ => Unit.Default).Subscribe());


            // Wait until we've loaded (or failed to load) an enterprise uri from the db and then
            // start tracking changes to the EnterpriseHost property and persist every change to the db
            disposables.Add(Observable.Concat(initialCacheLoadObs, persistEntepriseHostObs).Subscribe());
        }