Parcourir la source

[c#/beetlex] updates (#6399)

* update beetlex 1.4.3

update beetlex 1.4.3

* docker add COMPlus_ReadyToRun variable
update beetlex

* update beetlex, enabled thread queue

* beetlex framework add db and queries cases

* add db code

* change result json data

* update query url

* beetlex framework add fortunes cases

* change Content-Type

* add beetlex core cases

* fix queries cases

* update config

* change try readline

* update benchmark config

* Update README.md

* Update README.md

* change versus property

* beetlex-core update .net core to v3.0

* change beetlex-core project file

* beetlex update raw db class

* beetlex update raw db

* beetlex debug plaintext

* change debug docker file

* update beetlex to 1.4.0

* update

* beetlex update core 3.1

* [c#/beetlex] add updates cases

* [c#/beetlex] change Server: TFB, change custom connection pool, add update docker

* fix errors

* change pool init

* change connection pool maxsize

* fix fortunes errors

* clear DBRaw _connectionString value.

* [c#beetlex] change update dbconnection pool size

* [c#/beetlex] udpate spanjson to v3.0.1, Npgsql v5.0.0

* [c#/beetlex] add caching sample

* set connectionstring multiplexing

* remove connection multiplexing setting

* [c#/beetlex]change NpgsqlParameter to  NpgsqlParameter<T>

* [c#/beetlex] update dbraw

* [c#/beetlex] change connection string

* [c#/beetlex]  add fortunes cases to core-updb

* update beetlex 1.5.6

* update 5.0.0-alpha1

* update docker file

* Enabled IOQueues

* Set IOQueues debug mode

* update

* [c#/beetlex] udpate to v1.6.0.1-beta

* update pg drive

* [c#/beetlex] update to beetlex v1.6.3 and support pipelining

* set options

* [c#/beetlex] Optimized actions

* [c#/beetlex] update plaintext

* Bump ServiceStack in /frameworks/CSharp/servicestack/src/SelfHost

Bumps [ServiceStack](https://github.com/ServiceStack/ServiceStack) from 3.9.59 to 5.9.2.
- [Release notes](https://github.com/ServiceStack/ServiceStack/releases)
- [Commits](https://github.com/ServiceStack/ServiceStack/commits/v5.9.2)

Signed-off-by: dependabot[bot] <[email protected]>

* [c#/beetlex] change plaintext buffer size, optimize fortunes.

* [c#/beetlex] update v1.6.5,use System.Text.Json

* change docker files

* update beetlex 1.6.5.2

* [c#/beetlex] update v1.6.5.3-beta

* [c#/beetlex] update 1.6.5.36-beta

* update

* update json

* [c#/beetlex] update

* update beetlex 1.6.5.38 beta

* update

* add  array buffer

* [c#/beetlex] updates

* update

* update

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Henry il y a 4 ans
Parent
commit
b1fdcf25a3

+ 8 - 1
frameworks/CSharp/beetlex/PlatformBenchmarks/AsciiString.cs

@@ -27,7 +27,7 @@ namespace PlatformBenchmarks
             return str._data;
         }
 
-        public static implicit operator byte[] (AsciiString str)
+        public static implicit operator byte[](AsciiString str)
         {
             return str._data;
         }
@@ -42,6 +42,13 @@ namespace PlatformBenchmarks
             return Encoding.ASCII.GetString(_data);
         }
 
+        public int CopyTo(byte[] source,int offset)
+        {
+            var len = Length;
+            Buffer.BlockCopy(_data, 0, source, offset, len);
+            return len;
+        }
+
         public static explicit operator string(AsciiString str)
         {
             return str.ToString();

+ 1 - 1
frameworks/CSharp/beetlex/PlatformBenchmarks/DBRaw.cs

@@ -169,7 +169,7 @@ namespace PlatformBenchmarks
             SingleCommand.Connection = db;
             SingleCommand.Parameters[0].Value = _random.Next(1, 10001);
             var result = GetWorldBuffer();
-            for (int i = 0; i < result.Length; i++)
+            for (int i = 0; i < count; i++)
             {
                 result[i] = await ReadSingleRow(db, SingleCommand);
                 SingleCommand.Parameters[0].Value = _random.Next(1, 10001);

+ 61 - 0
frameworks/CSharp/beetlex/PlatformBenchmarks/HtmlBuffer.cs

@@ -0,0 +1,61 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PlatformBenchmarks
+{
+    public class HtmlBufferWriter
+    {
+
+        public HtmlBufferWriter(int size)
+        {
+            mData = new byte[size];
+        }
+        public void Write(byte data)
+        {
+            mData[mPostion] = data;
+            mPostion++;
+        }
+        public void Write(string value)
+        {
+            var len = Encoding.UTF8.GetBytes(value, 0, value.Length, mData, mPostion);
+            mPostion += len;
+        }
+        public void Write(byte[] data)
+        {
+            Write(data, 0, data.Length);
+        }
+
+        public void Write(byte[] data, int offset, int count)
+        {
+            if (count <= 8)
+            {
+                for (int i = 0; i < count; i++)
+                {
+                    mData[i + mPostion] = data[offset + i];
+                }
+            }
+            else
+            {
+                System.Buffer.BlockCopy(data, offset, mData, mPostion, count);
+            }
+            mPostion += count;
+        }
+
+        private byte[] mData;
+
+        private int mPostion = 0;
+
+        public byte[] Data => mData;
+
+        public int Length => mPostion;
+
+        public void Reset()
+        {
+            mPostion = 0;
+        }
+
+    }
+}

+ 54 - 42
frameworks/CSharp/beetlex/PlatformBenchmarks/HttpHandler.cs

@@ -29,6 +29,12 @@ namespace PlatformBenchmarks
 
         private static readonly AsciiString _headerContentTypeJson = "Content-Type: application/json\r\n";
 
+        private static readonly AsciiString _textResultHeader = _httpsuccess + _headerServer.ToString() + _headerContentTypeText.ToString();
+
+        private static readonly AsciiString _jsonResultHeader = _httpsuccess + _headerServer.ToString() + _headerContentTypeJson.ToString();
+
+        private static readonly AsciiString _htmlResultHeader = _httpsuccess + _headerServer.ToString() + _headerContentTypeHtml.ToString();
+
         private static readonly AsciiString _path_Json = "/json";
 
         private static readonly AsciiString _path_Db = "/db";
@@ -47,6 +53,8 @@ namespace PlatformBenchmarks
 
         private static byte _Space = 32;
 
+        public const int _LengthSize = 6;
+
         private static byte _question = 63;
 
         public HttpHandler()
@@ -105,20 +113,7 @@ namespace PlatformBenchmarks
                 if (result.Length == 2)
                 {
                     pipeStream.ReadFree(result.Length);
-                    if (Program.Debug)
-                    {
-                        if (token.CurrentRequest != null)
-                        {
-                            token.Requests.Enqueue(token.CurrentRequest);
-                            token.CurrentRequest = null;
-                            token.ThreadDispatcher.Enqueue(token);
-                        }
-                    }
-                    else
-                    {
-                        OnStartRequest(token.CurrentRequest, e.Session, token, pipeStream);
-                    }
-
+                    OnStartRequest(token.CurrentRequest, e.Session, token, pipeStream);
                 }
                 else
                 {
@@ -136,6 +131,7 @@ namespace PlatformBenchmarks
                         }
                         else
                         {
+                            token.CurrentRequest = request;
                             pipeStream.ReadFree((int)pipeStream.Length);
                             OnStartRequest(request, e.Session, token, pipeStream);
                             return;
@@ -239,83 +235,99 @@ namespace PlatformBenchmarks
 
         public virtual async Task OnStartRequest(RequestData data, ISession session, HttpToken token, PipeStream stream)
         {
-            OnWriteHeader(stream, token);
+            OnWriteHeader(stream, token, data.Action);
             ActionType type = data.Action;
             if (type == ActionType.Plaintext)
             {
-                stream.Write(_headerContentTypeText.Data, 0, _headerContentTypeText.Length);
-                OnWriteContentLength(stream, token);
                 await Plaintext(stream, token, session);
             }
             else if (type == ActionType.Json)
             {
-                stream.Write(_headerContentTypeJson.Data, 0, _headerContentTypeJson.Length);
-                OnWriteContentLength(stream, token);
                 await Json(stream, token, session);
             }
             else if (type == ActionType.Db)
             {
-                stream.Write(_headerContentTypeJson.Data, 0, _headerContentTypeJson.Length);
-                OnWriteContentLength(stream, token);
                 await db(stream, token, session);
             }
             else if (type == ActionType.Queries)
             {
-                stream.Write(_headerContentTypeJson.Data, 0, _headerContentTypeJson.Length);
-                OnWriteContentLength(stream, token);
                 await queries(data.QueryString, stream, token, session);
             }
-
             else if (type == ActionType.Caching)
             {
-                stream.Write(_headerContentTypeJson.Data, 0, _headerContentTypeJson.Length);
-                OnWriteContentLength(stream, token);
                 await caching(data.QueryString, stream, token, session);
             }
-
             else if (type == ActionType.Updates)
             {
-                stream.Write(_headerContentTypeJson.Data, 0, _headerContentTypeJson.Length);
-                OnWriteContentLength(stream, token);
                 await updates(data.QueryString, stream, token, session);
             }
             else if (type == ActionType.Fortunes)
             {
-                stream.Write(_headerContentTypeHtml.Data, 0, _headerContentTypeHtml.Length);
-                OnWriteContentLength(stream, token);
                 await fortunes(stream, token, session);
             }
             else
             {
-                stream.Write(_headerContentTypeHtml.Data, 0, _headerContentTypeHtml.Length);
-                OnWriteContentLength(stream, token);
                 await Default(stream, token, session);
             }
 
         }
 
-        private void OnWriteHeader(PipeStream stream, HttpToken token)
+        private void OnWriteHeader(PipeStream stream, HttpToken token, ActionType type)
         {
-            stream.Write(_httpsuccess.Data, 0, _httpsuccess.Length);
-            stream.Write(_headerServer.Data, 0, _headerServer.Length);
+            switch (type)
+            {
+                case ActionType.Caching:
+                case ActionType.Json:
+                case ActionType.Queries:
+                case ActionType.Db:
+                case ActionType.Updates:
+                    stream.Write(_jsonResultHeader.Data, 0, _jsonResultHeader.Length);
+                    break;
+                case ActionType.Plaintext:
+                    stream.Write(_textResultHeader.Data, 0, _textResultHeader.Length);
+                    break;
+                default:
+                    stream.Write(_htmlResultHeader.Data, 0, _htmlResultHeader.Length);
+                    break;
+            }
+
             ArraySegment<byte> date = GMTDate.Default.DATE;
             stream.Write(date.Array, date.Offset, date.Count);
+            OnWriteContentLength(stream, token);
         }
 
         private void OnWriteContentLength(PipeStream stream, HttpToken token)
         {
-            stream.Write(_headerContentLength.Data, 0, _headerContentLength.Length);
-            token.ContentLength = stream.Allocate(10);
-            stream.Write(_2line, 0, 4);
-            token.ContentPostion = stream.CacheLength;
+            var action = token.CurrentRequest.Action;
+            if (action == ActionType.Json)
+            {
+                stream.Write(_jsonPreamble.Data, 0, _jsonPreamble.Length);
+                stream.Write(_2line, 0, 4);
+            }
+            else if (action == ActionType.Plaintext)
+            {
+                stream.Write(_plaintextPreamble.Data, 0, _plaintextPreamble.Length);
+                stream.Write(_2line, 0, 4);
+            }
+            else
+            {
+                stream.Write(_headerContentLength.Data, 0, _headerContentLength.Length);
+                token.ContentLength = stream.Allocate(HttpHandler._LengthSize);
+                stream.Write(_2line, 0, 4);
+                token.ContentPostion = stream.CacheLength;
+            }
         }
 
         private void OnCompleted(PipeStream stream, ISession session, HttpToken token)
         {
-
-            token.FullLength((stream.CacheLength - token.ContentPostion).ToString());
+            var type = token.CurrentRequest.Action;
+            if (type != ActionType.Plaintext && type != ActionType.Json)
+            {
+                token.FullLength((stream.CacheLength - token.ContentPostion).ToString());
+            }
             if (token.Requests.IsEmpty && stream.Length == 0)
                 session.Stream.Flush();
+            token.CurrentRequest = null;
         }
 
     }

+ 3 - 3
frameworks/CSharp/beetlex/PlatformBenchmarks/HttpServer.cs

@@ -34,14 +34,14 @@ namespace PlatformBenchmarks
             ApiServer.Open();
             if (!Program.UpDB)
             {
-                RawDb._connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000";
-                //RawDb._connectionString = "Server=192.168.2.19;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
+               RawDb._connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000";
+               // RawDb._connectionString = "Server=192.168.2.19;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=256;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
             }
             else
             {
 
                 RawDb._connectionString = "Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=64;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3;Multiplexing=true;Write Coalescing Delay Us=500;Write Coalescing Buffer Threshold Bytes=1000";
-                //RawDb._connectionString = "Server=192.168.2.19;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=64;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
+               // RawDb._connectionString = "Server=192.168.2.19;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;Maximum Pool Size=64;NoResetOnClose=true;Enlist=false;Max Auto Prepare=3";
             }
             ApiServer.Log(LogType.Info, null, $"Debug mode [{Program.Debug}]");
             return Task.CompletedTask;

+ 10 - 1
frameworks/CSharp/beetlex/PlatformBenchmarks/HttpToken.cs

@@ -29,10 +29,19 @@ namespace PlatformBenchmarks
 
         public RequestData CurrentRequest { get; set; }
 
+        private HtmlBufferWriter mHtmlBufferWriter = null;
+
+        public HtmlBufferWriter GetHtmlBufferWriter()
+        {
+            if (mHtmlBufferWriter == null)
+                mHtmlBufferWriter = new HtmlBufferWriter(2048);
+            return mHtmlBufferWriter;
+        }
+
         public byte[] GetLengthBuffer(string length)
         {
             Encoding.ASCII.GetBytes(length, 0, length.Length, mLengthBuffer, 0);
-            for (int i = length.Length; i < 10; i++)
+            for (int i = length.Length; i < HttpHandler._LengthSize; i++)
             {
                 mLengthBuffer[i] = 32;
             }

+ 88 - 13
frameworks/CSharp/beetlex/PlatformBenchmarks/fortunes.cs

@@ -35,22 +35,37 @@ namespace PlatformBenchmarks
         {
             try
             {
-              
+
                 var data = await token.Db.LoadFortunesRows();
-                stream.Write(_fortunesTableStart.Data, 0, _fortunesTableStart.Length);
-                foreach (var item in data)
+                if (Program.Debug)
+                {
+                    var html = token.GetHtmlBufferWriter();
+                    html.Reset();
+                    html.Write(_fortunesTableStart.Data, 0, _fortunesTableStart.Length);
+                    foreach (var item in data)
+                    {
+                        html.Write(_fortunesRowStart.Data, 0, _fortunesRowStart.Length);
+                        WriteNumeric(html, (uint)item.Id);
+                        html.Write(_fortunesColumn.Data, 0, _fortunesColumn.Length);
+                        html.Write(HtmlEncoder.Encode(item.Message));
+                        html.Write(_fortunesRowEnd.Data, 0, _fortunesRowEnd.Length);
+                    }
+                    html.Write(_fortunesTableEnd.Data, 0, _fortunesTableEnd.Length);
+                    stream.Write(html.Data, 0, html.Length);
+                }
+                else
                 {
-                    stream.Write(_fortunesRowStart.Data, 0, _fortunesRowStart.Length);
-                    stream.Write(item.Id.ToString(CultureInfo.InvariantCulture));
-                    stream.Write(_fortunesColumn.Data, 0, _fortunesColumn.Length);
-                    if (mHtmlEncodeBuffer == null)
-                        mHtmlEncodeBuffer = new char[1024];
-                    HtmlEncoder.Encode(item.Message, mHtmlEncodeBuffer, out int consumed, out int writtens);
-                    //stream.Write(HtmlEncoder.Encode(item.Message));
-                    stream.Write(new ArraySegment<char>(mHtmlEncodeBuffer, 0, writtens));
-                    stream.Write(_fortunesRowEnd.Data, 0, _fortunesRowEnd.Length);
+                    stream.Write(_fortunesTableStart.Data, 0, _fortunesTableStart.Length);
+                    foreach (var item in data)
+                    {
+                        stream.Write(_fortunesRowStart.Data, 0, _fortunesRowStart.Length);
+                        WriteNumeric(stream, (uint)item.Id);
+                        stream.Write(_fortunesColumn.Data, 0, _fortunesColumn.Length);
+                        stream.Write(HtmlEncoder.Encode(item.Message));
+                        stream.Write(_fortunesRowEnd.Data, 0, _fortunesRowEnd.Length);
+                    }
+                    stream.Write(_fortunesTableEnd.Data, 0, _fortunesTableEnd.Length);
                 }
-                stream.Write(_fortunesTableEnd.Data, 0, _fortunesTableEnd.Length);
             }
             catch (Exception e_)
             {
@@ -59,5 +74,65 @@ namespace PlatformBenchmarks
             }
             OnCompleted(stream, session, token);
         }
+
+        internal void WriteNumeric(HtmlBufferWriter writer, uint number)
+        {
+            const byte AsciiDigitStart = (byte)'0';
+
+            if (number < 10)
+            {
+                writer.Write((byte)(number + AsciiDigitStart));
+
+            }
+            else if (number < 100)
+            {
+                var tens = (byte)((number * 205u) >> 11); // div10, valid to 1028
+                var span = new byte[2];
+                span[0] = (byte)(tens + AsciiDigitStart);
+                span[1] = (byte)(number - (tens * 10) + AsciiDigitStart);
+                writer.Write(span, 0, 2);
+
+            }
+            else if (number < 1000)
+            {
+                var digit0 = (byte)((number * 41u) >> 12); // div100, valid to 1098
+                var digits01 = (byte)((number * 205u) >> 11); // div10, valid to 1028
+                var span = new byte[3];
+                span[0] = (byte)(digit0 + AsciiDigitStart);
+                span[1] = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart);
+                span[2] = (byte)(number - (digits01 * 10) + AsciiDigitStart);
+                writer.Write(span, 0, 3);
+            }
+        }
+
+        internal void WriteNumeric(PipeStream stream, uint number)
+        {
+            const byte AsciiDigitStart = (byte)'0';
+
+            if (number < 10)
+            {
+                stream.WriteByte((byte)(number + AsciiDigitStart));
+
+            }
+            else if (number < 100)
+            {
+                var tens = (byte)((number * 205u) >> 11); // div10, valid to 1028
+                var span = new byte[2];
+                span[0] = (byte)(tens + AsciiDigitStart);
+                span[1] = (byte)(number - (tens * 10) + AsciiDigitStart);
+                stream.Write(span, 0, 2);
+
+            }
+            else if (number < 1000)
+            {
+                var digit0 = (byte)((number * 41u) >> 12); // div100, valid to 1098
+                var digits01 = (byte)((number * 205u) >> 11); // div10, valid to 1028
+                var span = new byte[3];
+                span[0] = (byte)(digit0 + AsciiDigitStart);
+                span[1] = (byte)(digits01 - (digit0 * 10) + AsciiDigitStart);
+                span[2] = (byte)(number - (digits01 * 10) + AsciiDigitStart);
+                stream.Write(span, 0, 3);
+            }
+        }
     }
 }

+ 5 - 0
frameworks/CSharp/beetlex/PlatformBenchmarks/json.cs

@@ -11,6 +11,11 @@ namespace PlatformBenchmarks
 {
     public partial class HttpHandler
     {
+        private readonly static uint _jsonPayloadSize = (uint)System.Text.Json.JsonSerializer.SerializeToUtf8Bytes(new JsonMessage { message = "Hello, World!" }, SerializerOptions).Length;
+
+        private readonly static AsciiString _jsonPreamble =
+            _headerContentLength + _jsonPayloadSize.ToString();
+
         private static readonly JsonSerializerOptions SerializerOptions = new JsonSerializerOptions();
 
         private static Utf8JsonWriter GetUtf8JsonWriter(PipeStream stream, HttpToken token)

+ 4 - 0
frameworks/CSharp/beetlex/PlatformBenchmarks/plaintext.cs

@@ -9,6 +9,10 @@ namespace PlatformBenchmarks
 {
     public partial class HttpHandler
     {
+        private readonly static AsciiString _plaintextPreamble =
+
+           _headerContentLength + _result_plaintext.Length.ToString();
+
         public ValueTask Plaintext(PipeStream stream, HttpToken token, ISession session)
         {
             stream.Write(_result_plaintext.Data, 0, _result_plaintext.Length);

+ 1 - 0
frameworks/CSharp/beetlex/config.toml

@@ -39,6 +39,7 @@ versus = "aspcore"
 [debug]
 urls.plaintext = "/plaintext"
 urls.json = "/json"
+urls.query = "/queries?queries="
 approach = "Realistic"
 classification = "Platform"
 database = "Postgres"