Example #1
0
        private static void CmdAppend(string[] args)
        {
            if (args.Length != 1 && args.Length != 2)
            {
                Console.WriteLine("Usage: append <stream> <local>?");
                Console.WriteLine("Appends events to a stream, discarding sequence ids.");
                return;
            }

            // The stream from which to append
            IReadOnlyList <EventData> from;

            if (args.Length == 1)
            {
                if (Current == null)
                {
                    Console.WriteLine("No current stream available.");
                    return;
                }

                from = Current;
            }
            else
            {
                if (!Fetched.TryGetValue(args[1], out from))
                {
                    Console.WriteLine("Stream '{0}' does not exist.", args[1]);
                    return;
                }
            }

            // The stream to which to append
            var into = args[0];

            var dstDriver = new StorageConfiguration(Parse(into)).Connect();

            using (Release(dstDriver))
            {
                var dst = new MigrationStream <JObject>(dstDriver);

                var sw     = Stopwatch.StartNew();
                var events = 0;

                Task.Run((Func <Task>)(async() =>
                {
                    Status("Current destination seq: ...");
                    var bakSeq = await dstDriver.GetLastKeyAsync();
                    Console.WriteLine("Current destination seq: {0}", bakSeq);

                    ++bakSeq;

                    while (events < @from.Count)
                    {
                        Status("Appending: {0}/{1}",
                               events,
                               @from.Count);

                        var list = new List <KeyValuePair <uint, JObject> >();
                        for (var i = 0; i < 1000 && events < @from.Count; ++i, ++events, ++bakSeq)
                        {
                            list.Add(new KeyValuePair <uint, JObject>(bakSeq, @from[events].Event));
                        }

                        events += list.Count;

                        await dst.WriteAsync(list);
                    }
                })).Wait();

                Console.WriteLine("Appended {0} events in {1:F2}s.",
                                  events,
                                  sw.ElapsedMilliseconds / 1000.0);
            }
        }
Example #2
0
        /// <summary> Copies from source to destination, returns last position in source. </summary>
        private static long BackupCopy(string srcname, string dstname, uint maxseq)
        {
            var srcDriver = new StorageConfiguration(Parse(srcname))
            {
                ReadOnly = true
            }.Connect();

            using (Release(srcDriver))
            {
                var dstDriver = new StorageConfiguration(Parse(dstname)).Connect();
                using (Release(dstDriver))
                {
                    var src = new EventStream <JObject>(srcDriver);
                    var dst = new MigrationStream <JObject>(dstDriver);

                    var sw      = Stopwatch.StartNew();
                    var events  = 0;
                    var initial = 0L;

                    Status("Connecting...");

                    Task.Run((Func <Task>)(async() =>
                    {
                        Status("Current source size: ...");
                        var maxPos = await srcDriver.GetPositionAsync();
                        Console.WriteLine("Current source size: {0:F2} MB", maxPos / (1024.0 * 1024.0));

                        Status("Current source seq: ...");
                        var maxSeq = await srcDriver.GetLastKeyAsync();
                        Console.WriteLine("Current source seq: {0}", maxSeq);

                        Status("Current destination seq: ...");
                        var bakSeq = await dstDriver.GetLastKeyAsync();
                        Console.WriteLine("Current destination seq: {0}", bakSeq);

                        if (bakSeq >= maxSeq)
                        {
                            Console.WriteLine("Destination already up-to-date.");
                            return;
                        }

                        var asAzure = ((ReadOnlyDriverWrapper)srcDriver).Wrapped as AzureStorageDriver;

                        if (asAzure != null)
                        {
                            for (var i = 0; i < asAzure.Blobs.Count; ++i)
                            {
                                Console.WriteLine("Blob {0}: {1:F2} MB from seq {2}",
                                                  asAzure.Blobs[i].Name,
                                                  asAzure.Blobs[i].Properties.Length / (1024.0 * 1024.0),
                                                  i < asAzure.FirstKey.Count ? asAzure.FirstKey[i] : maxSeq);
                            }
                        }

                        if (bakSeq > 0)
                        {
                            Status("Skipping to seq {0}...", bakSeq);
                            await src.DiscardUpTo(bakSeq + 1);
                            Console.WriteLine("Skipping to seq {0} done !", bakSeq);
                        }

                        initial = src.Position;

                        Func <bool> more;
                        do
                        {
                            var fetch = src.BackgroundFetchAsync();
                            var list  = new List <KeyValuePair <uint, JObject> >();

                            JObject obj;
                            while ((obj = src.TryGetNext()) != null)
                            {
                                list.Add(new KeyValuePair <uint, JObject>(src.Sequence, obj));
                            }

                            events += list.Count;

                            while (list.Count > 0 && list[list.Count - 1].Key > maxseq)
                            {
                                list.RemoveAt(list.Count - 1);
                            }

                            await dst.WriteAsync(list);

                            Status("{0}/{1} ({2:F2}/{3:F2} MB)",
                                   src.Sequence,
                                   maxSeq,
                                   src.Position / (1024.0 * 1024.0),
                                   maxPos / (1024.0 * 1024.0));

                            more = await fetch;
                        } while (more());
                    })).Wait();

                    Console.WriteLine("{0} events ({1:F2} MB) in {2:F2}s.",
                                      events,
                                      (src.Position - initial) / (1024.0 * 1024.0),
                                      sw.ElapsedMilliseconds / 1000.0);

                    return(src.Position);
                }
            }
        }