Beispiel #1
0
        public void Process(ExecutionContext context)
        {
            CmdStore  cs        = context.Store;
            StoreInfo storeInfo = cs.Store;
            string    upLoc     = storeInfo.UpstreamLocation;

            if (String.IsNullOrEmpty(upLoc))
            {
                throw new ApplicationException("There is no upstream location");
            }

            // Collate the number of commands we have in local branches
            IdCount[] have = cs.Branches.Values
                             .Where(x => !x.IsRemote)
                             .Select(x => new IdCount(x.Id, x.Info.CommandCount))
                             .ToArray();

            IRemoteStore rs = context.GetRemoteStore(upLoc);

            // We don't care about new branches in the origin, but we do care
            // about local branches that have been created since the last push
            IdRange[] toPush = rs.GetMissingRanges(cs.Id, have, false).ToArray();

            // How many commands do we need to push
            uint total = (uint)toPush.Sum(x => x.Size);

            Log.Info($"To push {total} command`s in {toPush.Length} branch`es".TrimExtras());

            foreach (IdRange idr in toPush)
            {
                Branch b = cs.FindBranch(idr.Id);
                if (b == null)
                {
                    throw new ApplicationException("Cannot locate branch " + idr.Id);
                }

                Log.Info($"Push [{idr.Min},{idr.Max}] from {b}");

                CmdData[] data = b.TakeRange(idr.Min, idr.Max).ToArray();
                rs.Push(cs.Name, b.Info, data);

                // Remember how much we were ahead at the time of the push
                b.Info.LastPush = idr.Max + 1;
                b.Store.SaveBranchInfo(b);
            }

            Log.Info("Push completed");
        }
Beispiel #2
0
        public void Process(ExecutionContext context)
        {
            CmdStore  cs        = context.Store;
            StoreInfo storeInfo = cs.Store;
            string    upLoc     = storeInfo.UpstreamLocation;

            if (String.IsNullOrEmpty(upLoc))
            {
                throw new ApplicationException("There is no upstream location");
            }

            // Collate how much we already have in all remote branches.
            // We may have previously pushed some local branches to the remote
            // store, but nothing is supposed to mutate those remote copies.

            IdCount[] have = cs.Branches.Values
                             .Where(x => x.IsRemote)
                             .Select(x => new IdCount(x.Id, x.Info.CommandCount))
                             .ToArray();

            // Open a channel to the upstream store
            IRemoteStore rs = context.GetRemoteStore(upLoc);

            // Determine what we are missing (including any new branches in the remote)
            IdRange[] toFetch = rs.GetMissingRanges(cs.Id, have, true);

            // How many commands do we need to fetch
            uint total = (uint)toFetch.Sum(x => x.Size);

            Log.Info($"To fetch {total} command`s from {toFetch.Length} branch`es".TrimExtras());

            // Retrieve the command data from the remote, keeping new branches
            // apart from appends to existing branches.

            var newBranchData  = new Dictionary <BranchInfo, CmdData[]>();
            var moreBranchData = new Dictionary <BranchInfo, CmdData[]>();

            foreach (IdRange idr in toFetch)
            {
                // Fetch the remote AC file
                BranchInfo ac = rs.GetBranchInfo(idr.Id);
                if (ac == null)
                {
                    throw new ApplicationException("Could not locate remote branch " + idr.Id);
                }

                // And the relevant data
                Log.Info($"Fetch [{idr.Min},{idr.Max}] for {ac.BranchName} ({ac.BranchId})");
                CmdData[] branchData = rs.GetData(idr).ToArray();

                if (cs.FindBranch(ac.BranchId) == null)
                {
                    newBranchData.Add(ac, branchData);
                }
                else
                {
                    moreBranchData.Add(ac, branchData);
                }
            }

            // All done with the remote store

            // Copy any brand new branches (ensuring they get created in the
            // right order so that parent/child relationships can be formed
            // as we go).

            foreach (KeyValuePair <BranchInfo, CmdData[]> kvp in newBranchData.OrderBy(x => x.Key.CreatedAt))
            {
                cs.CopyIn(kvp.Key, kvp.Value);
            }

            // Append command data for branches we previously had (the order
            // shouldn't matter)

            foreach (KeyValuePair <BranchInfo, CmdData[]> kvp in moreBranchData)
            {
                cs.CopyIn(kvp.Key, kvp.Value);
            }

            Log.Info("Fetch completed");

            // Reload the current command stream (from scratch, kind of brute force,
            // not sure whether appending the new commands would really be sufficient)
            // TODO: Is this really necessary? Perhaps only if the current branch has
            // been fetched (the stuff we're fetching should only come from remotes,
            // but the current branch could be one of those remotes)
            //cs.Stream = new CmdStream(cs.Current);
        }