Explorar o código

[genhttp] Update to 10.2 (#10393)

* Revert "[genhttp] Improve database performance (#10340)"

This reverts commit 0446810b68ab1d72da640b2116076b2be11bf2d8.

* Update to GenHTTP 10.2

* Fix build
Andreas Nägeli hai 1 semana
pai
achega
ed607b702d

+ 3 - 9
frameworks/CSharp/genhttp/Benchmarks/Benchmarks.csproj

@@ -28,19 +28,13 @@
 
     <ItemGroup>
 
-        <PackageReference Include="$(GENHTTP_ENGINE_PACKAGE)" Version="10.1.0" />
+        <PackageReference Include="$(GENHTTP_ENGINE_PACKAGE)" Version="10.2.0" />
 
-        <PackageReference Include="GenHTTP.Modules.Webservices" Version="10.1.0" />
+        <PackageReference Include="GenHTTP.Modules.Webservices" Version="10.2.0" />
 
-        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.0" />
+        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="10.0.1" />
         <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="10.0.0" />
 
-        <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="10.0.0" PrivateAssets="all" />
-        
-    </ItemGroup>
-
-    <ItemGroup>
-      <Folder Include="Model\CompiledModel\" />
     </ItemGroup>
 
 </Project>

+ 0 - 9
frameworks/CSharp/genhttp/Benchmarks/Model/CompiledModel/DatabaseContextAssemblyAttributes.cs

@@ -1,9 +0,0 @@
-// <auto-generated />
-using Benchmarks;
-using Benchmarks.Model;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-
-#pragma warning disable 219, 612, 618
-#nullable disable
-
-[assembly: DbContextModel(typeof(DatabaseContext), typeof(DatabaseContextModel))]

+ 0 - 48
frameworks/CSharp/genhttp/Benchmarks/Model/CompiledModel/DatabaseContextModel.cs

@@ -1,48 +0,0 @@
-// <auto-generated />
-using Benchmarks.Model;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-
-#pragma warning disable 219, 612, 618
-#nullable disable
-
-namespace Benchmarks
-{
-    [DbContext(typeof(DatabaseContext))]
-    public partial class DatabaseContextModel : RuntimeModel
-    {
-        private static readonly bool _useOldBehavior31751 =
-            System.AppContext.TryGetSwitch("Microsoft.EntityFrameworkCore.Issue31751", out var enabled31751) && enabled31751;
-
-        static DatabaseContextModel()
-        {
-            var model = new DatabaseContextModel();
-
-            if (_useOldBehavior31751)
-            {
-                model.Initialize();
-            }
-            else
-            {
-                var thread = new System.Threading.Thread(RunInitialization, 10 * 1024 * 1024);
-                thread.Start();
-                thread.Join();
-
-                void RunInitialization()
-                {
-                    model.Initialize();
-                }
-            }
-
-            model.Customize();
-            _instance = (DatabaseContextModel)model.FinalizeModel();
-        }
-
-        private static DatabaseContextModel _instance;
-        public static IModel Instance => _instance;
-
-        partial void Initialize();
-
-        partial void Customize();
-    }
-}

+ 0 - 32
frameworks/CSharp/genhttp/Benchmarks/Model/CompiledModel/DatabaseContextModelBuilder.cs

@@ -1,32 +0,0 @@
-// <auto-generated />
-using System;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#pragma warning disable 219, 612, 618
-#nullable disable
-
-namespace Benchmarks
-{
-    public partial class DatabaseContextModel
-    {
-        private DatabaseContextModel()
-            : base(skipDetectChanges: false, modelId: new Guid("e6a922c5-5e25-4191-8617-6c6410b754cc"), entityTypeCount: 2)
-        {
-        }
-
-        partial void Initialize()
-        {
-            var fortune = FortuneEntityType.Create(this);
-            var world = WorldEntityType.Create(this);
-
-            FortuneEntityType.CreateAnnotations(fortune);
-            WorldEntityType.CreateAnnotations(world);
-
-            AddAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
-            AddAnnotation("ProductVersion", "10.0.0");
-            AddAnnotation("Relational:MaxIdentifierLength", 63);
-        }
-    }
-}

+ 0 - 68
frameworks/CSharp/genhttp/Benchmarks/Model/CompiledModel/FortuneEntityType.cs

@@ -1,68 +0,0 @@
-// <auto-generated />
-using System;
-using System.Reflection;
-using Benchmarks.Model;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#pragma warning disable 219, 612, 618
-#nullable disable
-
-namespace Benchmarks
-{
-    [EntityFrameworkInternal]
-    public partial class FortuneEntityType
-    {
-        public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null)
-        {
-            var runtimeEntityType = model.AddEntityType(
-                "Benchmarks.Model.Fortune",
-                typeof(Fortune),
-                baseEntityType,
-                propertyCount: 2,
-                keyCount: 1);
-
-            var id = runtimeEntityType.AddProperty(
-                "Id",
-                typeof(int),
-                propertyInfo: typeof(Fortune).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                fieldInfo: typeof(Fortune).GetField("<Id>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                valueGenerated: ValueGenerated.OnAdd,
-                afterSaveBehavior: PropertySaveBehavior.Throw,
-                sentinel: 0);
-            id.AddAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
-            id.AddAnnotation("Relational:ColumnName", "id");
-
-            var message = runtimeEntityType.AddProperty(
-                "Message",
-                typeof(string),
-                propertyInfo: typeof(Fortune).GetProperty("Message", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                fieldInfo: typeof(Fortune).GetField("<Message>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                nullable: true,
-                maxLength: 2048);
-            message.AddAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None);
-            message.AddAnnotation("Relational:ColumnName", "message");
-
-            var key = runtimeEntityType.AddKey(
-                new[] { id });
-            runtimeEntityType.SetPrimaryKey(key);
-
-            return runtimeEntityType;
-        }
-
-        public static void CreateAnnotations(RuntimeEntityType runtimeEntityType)
-        {
-            runtimeEntityType.AddAnnotation("Relational:FunctionName", null);
-            runtimeEntityType.AddAnnotation("Relational:Schema", null);
-            runtimeEntityType.AddAnnotation("Relational:SqlQuery", null);
-            runtimeEntityType.AddAnnotation("Relational:TableName", "fortune");
-            runtimeEntityType.AddAnnotation("Relational:ViewName", null);
-            runtimeEntityType.AddAnnotation("Relational:ViewSchema", null);
-
-            Customize(runtimeEntityType);
-        }
-
-        static partial void Customize(RuntimeEntityType runtimeEntityType);
-    }
-}

+ 0 - 67
frameworks/CSharp/genhttp/Benchmarks/Model/CompiledModel/WorldEntityType.cs

@@ -1,67 +0,0 @@
-// <auto-generated />
-using System;
-using System.Reflection;
-using Benchmarks.Model;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#pragma warning disable 219, 612, 618
-#nullable disable
-
-namespace Benchmarks
-{
-    [EntityFrameworkInternal]
-    public partial class WorldEntityType
-    {
-        public static RuntimeEntityType Create(RuntimeModel model, RuntimeEntityType baseEntityType = null)
-        {
-            var runtimeEntityType = model.AddEntityType(
-                "Benchmarks.Model.World",
-                typeof(World),
-                baseEntityType,
-                propertyCount: 2,
-                keyCount: 1);
-
-            var id = runtimeEntityType.AddProperty(
-                "Id",
-                typeof(int),
-                propertyInfo: typeof(World).GetProperty("Id", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                fieldInfo: typeof(World).GetField("<Id>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                valueGenerated: ValueGenerated.OnAdd,
-                afterSaveBehavior: PropertySaveBehavior.Throw,
-                sentinel: 0);
-            id.AddAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn);
-            id.AddAnnotation("Relational:ColumnName", "id");
-
-            var randomNumber = runtimeEntityType.AddProperty(
-                "RandomNumber",
-                typeof(int),
-                propertyInfo: typeof(World).GetProperty("RandomNumber", BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                fieldInfo: typeof(World).GetField("<RandomNumber>k__BackingField", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly),
-                sentinel: 0);
-            randomNumber.AddAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.None);
-            randomNumber.AddAnnotation("Relational:ColumnName", "randomnumber");
-
-            var key = runtimeEntityType.AddKey(
-                new[] { id });
-            runtimeEntityType.SetPrimaryKey(key);
-
-            return runtimeEntityType;
-        }
-
-        public static void CreateAnnotations(RuntimeEntityType runtimeEntityType)
-        {
-            runtimeEntityType.AddAnnotation("Relational:FunctionName", null);
-            runtimeEntityType.AddAnnotation("Relational:Schema", null);
-            runtimeEntityType.AddAnnotation("Relational:SqlQuery", null);
-            runtimeEntityType.AddAnnotation("Relational:TableName", "world");
-            runtimeEntityType.AddAnnotation("Relational:ViewName", null);
-            runtimeEntityType.AddAnnotation("Relational:ViewSchema", null);
-
-            Customize(runtimeEntityType);
-        }
-
-        static partial void Customize(RuntimeEntityType runtimeEntityType);
-    }
-}

+ 0 - 15
frameworks/CSharp/genhttp/Benchmarks/Model/Database.cs

@@ -1,15 +0,0 @@
-namespace Benchmarks.Model;
-
-public static class Database
-{
-    public static readonly DatabaseContextPool<DatabaseContext> NoTrackingPool;
-
-    public static readonly DatabaseContextPool<DatabaseContext> TrackingPool;
-
-    static Database()
-    {
-        NoTrackingPool = new DatabaseContextPool<DatabaseContext>(factory: DatabaseContext.CreateNoTracking, maxSize: 512);
-        TrackingPool = new DatabaseContextPool<DatabaseContext>(factory: DatabaseContext.CreateTracking, maxSize: 512);
-    }
-
-}

+ 18 - 23
frameworks/CSharp/genhttp/Benchmarks/Model/DatabaseContext.cs

@@ -1,48 +1,43 @@
 using Microsoft.EntityFrameworkCore;
-using Microsoft.Extensions.DependencyInjection;
 
 namespace Benchmarks.Model;
 
 public sealed class DatabaseContext : DbContext
 {
-    private static readonly Lazy<DbContextOptions<DatabaseContext>> TrackingOptions = new(() => CreateOptions(true), LazyThreadSafetyMode.ExecutionAndPublication);
+    private static DbContextOptions<DatabaseContext> _options;
 
-    private static readonly Lazy<DbContextOptions<DatabaseContext>> NoTrackingOptions = new(() => CreateOptions(false), LazyThreadSafetyMode.ExecutionAndPublication);
+    private static DbContextOptions<DatabaseContext> _noTrackingOptions;
 
-    public static DatabaseContext CreateTracking() => new(TrackingOptions.Value, true);
+    #region Factory
 
-    public static DatabaseContext CreateNoTracking() => new(NoTrackingOptions.Value, false);
+    public static DatabaseContext Create() => new(_options ??= GetOptions(true));
 
-    private static DbContextOptions<DatabaseContext> CreateOptions(bool tracking)
-    {
-        var services = new ServiceCollection();
-
-        services.AddEntityFrameworkNpgsql();
-
-        var provider = services.BuildServiceProvider();
+    public static DatabaseContext CreateNoTracking() => new(_noTrackingOptions ??= GetOptions(false));
 
-        var builder = new DbContextOptionsBuilder<DatabaseContext>();
+    private static DbContextOptions<DatabaseContext> GetOptions(bool tracking)
+    {
+        var optionsBuilder = new DbContextOptionsBuilder<DatabaseContext>();
 
-        builder.UseInternalServiceProvider(provider)
-               .UseNpgsql("Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;SSL Mode=Disable;Maximum Pool Size=512;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4;Multiplexing=true")
-               .EnableThreadSafetyChecks(false)
-               .UseModel(DatabaseContextModel.Instance);
+        optionsBuilder.UseNpgsql("Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;SSL Mode=Disable;Maximum Pool Size=512;NoResetOnClose=true;Enlist=false;Max Auto Prepare=4");
 
         if (!tracking)
         {
-            builder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
+            optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
         }
 
-        return builder.Options;
+        return optionsBuilder.Options;
     }
 
-    internal DatabaseContext(DbContextOptions<DatabaseContext> options, bool tracking = false) : base(options)
-    {
-        ChangeTracker.AutoDetectChangesEnabled = tracking;
-    }
+    private DatabaseContext(DbContextOptions options) : base(options) { }
+
+    #endregion
+
+    #region Entities
 
     public DbSet<World> World { get; set; }
 
     public DbSet<Fortune> Fortune { get; set; }
 
+    #endregion
+
 }

+ 0 - 18
frameworks/CSharp/genhttp/Benchmarks/Model/DatabaseContextFactory.cs

@@ -1,18 +0,0 @@
-namespace Benchmarks.Model;
-
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Design;
-
-public class DatabaseContextFactory : IDesignTimeDbContextFactory<DatabaseContext>
-{
-
-    public DatabaseContext CreateDbContext(string[] args)
-    {
-        var options = new DbContextOptionsBuilder<DatabaseContext>()
-                      .UseNpgsql("Server=tfb-database;Database=hello_world;User Id=benchmarkdbuser;Password=benchmarkdbpass;SSL Mode=Disable")
-                      .Options;
-
-        return new DatabaseContext(options);
-    }
-
-}

+ 0 - 46
frameworks/CSharp/genhttp/Benchmarks/Model/DatabaseContextPool.cs

@@ -1,46 +0,0 @@
-namespace Benchmarks.Model;
-
-using System.Collections.Concurrent;
-
-using Microsoft.EntityFrameworkCore;
-
-public sealed class DatabaseContextPool<TContext> where TContext : DbContext
-{
-    private readonly ConcurrentBag<TContext> _pool = new();
-
-    private readonly Func<TContext> _factory;
-
-    private readonly int _maxSize;
-
-    public DatabaseContextPool(Func<TContext> factory, int maxSize)
-    {
-        _factory = factory;
-        _maxSize = maxSize;
-    }
-
-    public TContext Rent()
-    {
-        if (_pool.TryTake(out var ctx))
-        {
-            ctx.ChangeTracker.Clear();
-            return ctx;
-        }
-
-        return _factory();
-    }
-
-    public void Return(TContext context)
-    {
-        if (_pool.Count >= _maxSize)
-        {
-            context.Dispose();
-            return;
-        }
-
-
-        context.ChangeTracker.Clear();
-
-        _pool.Add(context);
-    }
-
-}

+ 14 - 21
frameworks/CSharp/genhttp/Benchmarks/Tests/CacheResource.cs

@@ -37,36 +37,29 @@ public sealed class CacheResource
 
         var result = new List<World>(count);
 
-        var context = Database.NoTrackingPool.Rent();
+        await using var context = DatabaseContext.CreateNoTracking();
 
-        try
+        for (var i = 0; i < count; i++)
         {
-            for (var i = 0; i < count; i++)
-            {
-                var id = Random.Next(1, 10001);
+            var id = Random.Next(1, 10001);
 
-                var key = CacheKeys[id];
+            var key = CacheKeys[id];
 
-                var data = Cache.Get<World>(key);
+            var data = Cache.Get<World>(key);
 
-                if (data != null)
-                {
-                    result.Add(data);
-                }
-                else
-                {
-                    var resolved = await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false);
+            if (data != null)
+            {
+                result.Add(data);
+            }
+            else
+            {
+                var resolved = await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false);
 
-                    Cache.Set(key, resolved);
+                Cache.Set(key, resolved);
 
-                    result.Add(resolved);
-                }
+                result.Add(resolved);
             }
         }
-        finally
-        {
-            Database.NoTrackingPool.Return(context);
-        }
 
         return result;
     }

+ 2 - 9
frameworks/CSharp/genhttp/Benchmarks/Tests/DbResource.cs

@@ -13,16 +13,9 @@ public sealed class DbResource
     {
         var id = Random.Next(1, 10001);
 
-        var context = Database.NoTrackingPool.Rent();
+        await using var context = DatabaseContext.CreateNoTracking();
 
-        try
-        {
-            return await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false);
-        }
-        finally
-        {
-            Database.NoTrackingPool.Return(context);
-        }
+        return await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false);
     }
 
 }

+ 21 - 28
frameworks/CSharp/genhttp/Benchmarks/Tests/FortuneHandler.cs

@@ -48,43 +48,36 @@ public class FortuneHandler : IHandler
 
     private static async ValueTask<List<Value>> GetFortunes()
     {
-        var context = Database.NoTrackingPool.Rent();
+        await using var context = DatabaseContext.CreateNoTracking();
 
-        try
-        {
-            var fortunes = await context.Fortune.ToListAsync().ConfigureAwait(false);
-
-            var result = new List<Value>(fortunes.Count + 1);
+        var fortunes = await context.Fortune.ToListAsync().ConfigureAwait(false);
 
-            foreach (var fortune in fortunes)
-            {
-                result.Add(Value.FromDictionary(new Dictionary<Value, Value>()
-                {
-                    ["id"] = fortune.Id,
-                    ["message"] = HttpUtility.HtmlEncode(fortune.Message)
-                }));
-            }
+        var result = new List<Value>(fortunes.Count + 1);
 
+        foreach (var fortune in fortunes)
+        {
             result.Add(Value.FromDictionary(new Dictionary<Value, Value>()
             {
-                ["id"] = 0,
-                ["message"] = "Additional fortune added at request time."
+                ["id"] = fortune.Id,
+                ["message"] = HttpUtility.HtmlEncode(fortune.Message)
             }));
+        }
 
-            result.Sort((one, two) =>
-            {
-                var firstMessage = one.Fields["message"].AsString;
-                var secondMessage = two.Fields["message"].AsString;
-
-                return string.Compare(firstMessage, secondMessage, StringComparison.Ordinal);
-            });
+        result.Add(Value.FromDictionary(new Dictionary<Value, Value>()
+        {
+            ["id"] = 0,
+            ["message"] = "Additional fortune added at request time."
+        }));
 
-            return result;
-        }
-        finally
+        result.Sort((one, two) =>
         {
-            Database.NoTrackingPool.Return(context);
-        }
+            var firstMessage = one.Fields["message"].AsString;
+            var secondMessage = two.Fields["message"].AsString;
+
+            return string.Compare(firstMessage, secondMessage, StringComparison.Ordinal);
+        });
+
+        return result;
     }
 
     #endregion

+ 5 - 12
frameworks/CSharp/genhttp/Benchmarks/Tests/QueryResource.cs

@@ -29,23 +29,16 @@ public sealed class QueryResource
 
         var result = new List<World>(count);
 
-        var context = Database.NoTrackingPool.Rent();
+        using var context = DatabaseContext.CreateNoTracking();
 
-        try
+        for (var _ = 0; _ < count; _++)
         {
-            for (var _ = 0; _ < count; _++)
-            {
-                var id = Random.Next(1, 10001);
+            var id = Random.Next(1, 10001);
 
-                result.Add(await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false));
-            }
-        }
-        finally
-        {
-            Database.NoTrackingPool.Return(context);
+            result.Add(await context.World.FirstOrDefaultAsync(w => w.Id == id).ConfigureAwait(false));
         }
 
         return result;
     }
 
-}
+}

+ 2 - 8
frameworks/CSharp/genhttp/Benchmarks/Tests/UpdateResource.cs

@@ -31,9 +31,7 @@ public sealed class UpdateResource
 
         var ids = Enumerable.Range(1, 10000).Select(x => Random.Next(1, 10001)).Distinct().Take(count).ToArray();
 
-        var context = Database.TrackingPool.Rent();
-
-        try
+        using (var context = DatabaseContext.Create())
         {
             foreach (var id in ids)
             {
@@ -60,11 +58,7 @@ public sealed class UpdateResource
                 await context.SaveChangesAsync();
             }
         }
-        finally
-        {
-            Database.TrackingPool.Return(context);
-        }
 
         return result;
     }
-}
+}

+ 2 - 2
frameworks/CSharp/genhttp/Benchmarks/Utilities/FixedLengthJsonContent.cs

@@ -8,13 +8,13 @@ namespace Benchmarks.Utilities;
 
 public sealed class FixedLengthJsonContent : IResponseContent
 {
-    private readonly MemoryStream _buffer = new();
+    private readonly MemoryStream _buffer = new(27);
 
     public ulong? Length => (ulong)_buffer.Length;
 
     public FixedLengthJsonContent(JsonResult result)
     {
-        JsonSerializer.SerializeAsync(_buffer, result);
+        JsonSerializer.Serialize(_buffer, result);
     }
     
     public ValueTask<ulong?> CalculateChecksumAsync() => throw new NotImplementedException();