Bend.Repl.ReplHandler.worker_fullRebuild C# (CSharp) Method

worker_fullRebuild() private method

private worker_fullRebuild ( ) : void
return void
        private void worker_fullRebuild()
        {
            IReplConnection srvr;
            // TODO: make sure servers are only listed as seeds when they are "active".
            try {
                srvr = pusher.getRandomSeed();
                // double check that we didn't get ourself, because that won't work
                if (srvr.getServerGuid().CompareTo(this.getServerGuid()) == 0) {
                    Console.WriteLine("******************* ERROR: getRandomSeed() returned US when we're trying to full rebuild");
                    this.state = ReplState.error;
                    return;
                }
            } catch (ReplPusher.NoServersAvailableException) {
                Console.WriteLine("Repl({0}): fullRebuild - no servers available... return to init",
                    ctx.server_guid);
                this.state = ReplState.init;
                return;
            }

            // (1) clear our keyspace

            // TODO: How do we trigger a reinit on a new prefix, so we don't
            //   have to actually delete everything??  Maybe we can make SubsetStage
            //   capable of clearing by dropping the old prefix-id?  Or maybe we will
            //   use built-in support for a range-deletion-tombstone?

            // TODO: how do we verify that this isn't going to lose important information?

            // TODO: probably should just delete/copy _data and _logs
            //     so we don't lose our seeds and config info
            Console.WriteLine("Rebuild({0}): deleting our keys", ctx.server_guid);
            foreach (var row in this.next_stage.scanForward(ScanRange<RecordKey>.All())) {
                Console.WriteLine("   Rebuild({0}): deleting {1}", ctx.server_guid, row);
                this.next_stage.setValue(row.Key, RecordUpdate.DeletionTombstone());
            }

            // (2) re-record our data-instance id, so we don't get confused
            next_stage.setValue(new RecordKey()
            .appendKeyPart("_config")
            .appendKeyPart("DATA-INSTANCE-ID"),
            RecordUpdate.WithPayload(this.data_instance_id));

            // (3) ask for a snapshot

            IStepsKVDB snapshot = srvr.getSnapshot();

            // (4) then copy the snapshot

            // TODO: make sure we get data keys before logs, or that we do something to
            //      be sure to know whether this copy completes successfully or not.
            // TODO: probably want to record our copy-progress, so we can continue copy after
            //      restart without having to do it from scratch!!

            // TODO: need to be able to see tombstones in this scan!!
            foreach (var row in snapshot.scanForward(ScanRange<RecordKey>.All())) {
                Console.WriteLine("    + Rebuild({0}) setValue: {1}", ctx.server_guid, row);
                this.next_stage.setValue(row.Key,RecordUpdate.WithPayload(row.Value.data));
            }

            // (5) make sure to record our server-id correctly
            next_stage.setValue(new RecordKey()
            .appendKeyPart("_config")
            .appendKeyPart("MY-SERVER-ID"),
            RecordUpdate.WithPayload(ctx.server_guid));

            // (6) if our log is empty, write our log-start
            LogStatus status = this.getStatusForLog(ctx.server_guid);
            if (status.log_commit_head.GetLong().CompareTo(0) == 0) {
                next_stage.setValue(new RecordKey()
                    .appendKeyPart("_logs")
                    .appendKeyPart(ctx.server_guid)
                    .appendKeyPart(new RecordKeyType_Long(0)),
                    RecordUpdate.WithPayload(new byte[0]));
            }

            // (7) make sure there is a seed/log entry for ourselves
            next_stage.setValue(new RecordKey()
                .appendKeyPart("_config").appendKeyPart("seeds").appendKeyPart(ctx.server_guid),
                RecordUpdate.WithPayload(""));

            Console.WriteLine("Rebuild({0}): finished, sending to init", ctx.server_guid);
            this.state = ReplState.init; // now we should be able to log resume!!
        }