Пример #1
0
        public void interlock_exchange_delegate_pointer()
        {
            var subject  = new IEDP();
            var switches = new bool[500];

            var dispatcher = Dispatch <int> .CreateDefaultMultithreaded($"TEST: {nameof(interlock_exchange_delegate_pointer)}", threadCount : 10);

            for (int i = 0; i < 500; i++)
            {
                dispatcher.AddWork(i);
            }

            dispatcher.AddConsumer(i => {
                Thread.Sleep(i % 20);
                var x = subject.TryGetNextPage();
                Console.Write($"{i}=>{x}, ");
                switches[x] = true;
            });

            dispatcher.Start();
            dispatcher.WaitForEmptyQueueAndStop(TimeSpan.FromSeconds(10));

            Assert.That(switches.All(v => v), Is.True, "Not all switches were set");


            // Thought... keep a pool of about 32 slots that we keep free page indexes in. (that's about 128kb worth)
            // Each requester goes through the IEDP to get a number from 0..31, and pulls the page from there.
            // If there isn't a page in our slot, we hit the slow path and rebuild the slots.
        }
Пример #2
0
        public void reading_documents_in_multiple_threads_works_correctly()
        {
            using (var doc = MakeTestDocument())
                using (var ms = new MemoryStream())
                {
                    var subject = Database.TryConnect(ms);

                    Console.WriteLine("Writing doc");
                    doc.Seek(0, SeekOrigin.Begin);
                    subject.WriteDocument("test/data-path/doc", doc);

                    var dispatcher = Dispatch <int> .CreateDefaultMultithreaded("MyTask", threadCount : 10);

                    for (int i = 0; i < 500; i++)
                    {
                        dispatcher.AddWork(i);
                    }

                    dispatcher.AddConsumer(i => {
                        //Thread.Sleep(i % 8);
                        Console.Write($"{i}, ");
                        subject.Get("test/data-path/doc", out _);
                        subject.Get("this document is not here", out _);
                    });

                    dispatcher.Start();
                    dispatcher.WaitForEmptyQueueAndStop(TimeSpan.FromSeconds(10));
                }
        }
Пример #3
0
        static void Main()
        {
            using (var subject = new DirectServer(@"C:\Temp\WrappedSites_Disabled\no_appins")) // a published site
            {
                var request = new SerialisableRequest {
                    Method     = "GET",
                    RequestUri = "/values",
                    Headers    = new Dictionary <string, string> {
                        { "Content-Type", "application/json" }
                    },
                    Content = null
                };

                // Make a whole load of calls for profiling
                int i;
                var dispatcher = Dispatch <SerialisableRequest> .CreateDefaultMultithreaded("LoadTest", 4);

                dispatcher.AddConsumer(rq =>
                {
                    // ReSharper disable once AccessToDisposedClosure
                    var result = subject.DirectCall(request);
                    if (rq.CommandControl != null)
                    {
                        var resultString = Encoding.UTF8.GetString(result?.Content ?? new byte[0]);
                        Console.Write(rq.CommandControl);
                        Console.WriteLine(resultString);
                    }
                });

                var sw = new Stopwatch();
                sw.Start();
                dispatcher.Start();

                for (i = 0; i < 10000; i++)
                {
                    if (i % 100 == 0)
                    {
                        var traceRequest = request.Clone();
                        traceRequest.CommandControl = i.ToString();
                        dispatcher.AddWork(traceRequest);
                    }
                    else
                    {
                        dispatcher.AddWork(request);
                    }
                }
                dispatcher.WaitForEmptyQueueAndStop();  // only call this if you're not filling the queue from elsewhere


                sw.Stop();
                var rate = i / sw.Elapsed.TotalSeconds;
                Console.WriteLine("calls per second: " + rate);



                Console.WriteLine("[Done]");
                Console.ReadLine();
            }
        }
Пример #4
0
        public void writing_documents_in_multiple_threads_works_correctly()
        {
            using (var ms = new MemoryStream())
            {
                var subject = Database.TryConnect(ms);

                var dispatcher = Dispatch <int> .CreateDefaultMultithreaded("MyTask", threadCount : 10);

                const int rounds = 50;
                for (int i = 0; i < rounds; i++)
                {
                    dispatcher.AddWork(i);
                }

                dispatcher.AddConsumer(i => {
                    var j = (5 * i) % rounds;
                    Console.Write($"W{i},R{j}; ");
                    // ReSharper disable AccessToDisposedClosure
                    subject.WriteDocument($"test/data-path/{i}", MakeTestDocument());
                    subject.Get($"test/data-path/{j}", out _);
                    // ReSharper restore AccessToDisposedClosure
                });

                dispatcher.Start();
                dispatcher.WaitForEmptyQueueAndStop();

                subject.Flush();
                ms.Rewind();
                var rawData = ms.ToArray();

                // Check we can still load and read the database
                var result = Database.TryConnect(new MemoryStream(rawData));

                Console.WriteLine(string.Join(", ", result.Search("test")));

                var failed = new List <int>();

                for (int i = 0; i < rounds; i++)
                {
                    var ok = result.Get($"test/data-path/{i}", out _);
                    if (!ok)
                    {
                        failed.Add(i);
                    }
                }

                Assert.That(failed, Is.Empty, "Failed lookups: " + string.Join(", ", failed));
            }
        }
Пример #5
0
        public void Listen(CancellationToken token, IEnumerable <Endpoint> endpoints)
        {
            ThreadPool.SetMaxThreads(Parallelism, Parallelism);
            ThreadPool.SetMinThreads(1, 1);

            _dispatcher = Dispatch <IContext> .CreateDefaultMultithreaded("ResponderThreads", Parallelism);

            _dispatcher.AddConsumer(_handler.Handle);
            _dispatcher.Start(); // To use thread pool instead of dispatcher: don't call this and change the code in ListenerCallback

            var listener = new HttpListener();

            Trace.TraceInformation("Binding...");
            MainRequestHandler.HttpsAvailable = false;
            foreach (var endpoint in endpoints)
            {
                try
                {
                    var name    = endpoint.Name;
                    var baseUri = $"{endpoint.Protocol}://{endpoint.IPEndpoint}/";

                    if (endpoint.Protocol == "https")
                    {
                        MainRequestHandler.HttpsAvailable = true;
                    }

                    listener.Prefixes.Add(baseUri);

                    Trace.TraceInformation("Adding listener for '" + name + "' on " + baseUri);
                }
                catch (Exception ex)
                {
                    Trace.Fail("BINDING FAILED! " + ex);
                    return;
                }
            }

            Trace.TraceInformation("Starting...");
            try
            {
                listener.IgnoreWriteExceptions = false;//true;
                listener.Start();
            }
            catch (Exception ex)
            {
                Trace.Fail("STARTING FAILED! " + ex);
                return;
            }
            Trace.TraceInformation("Started");


            while (!token.IsCancellationRequested)
            {
                var asctx  = listener.BeginGetContext(ListenerCallback, listener);
                var gotOne = asctx.AsyncWaitHandle.WaitOne(1500, true); // break out of wait loop to allow cancellation to happen.

                if (gotOne)
                {
                    Trace.TraceInformation("Incoming message");
                }
                else
                {
                    OnPeriodicCheck();
                }
            }

            listener.Stop();
            listener.Close();
            _dispatcher.Stop();
        }