RestService.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. using System;
  2. using System.ComponentModel;
  3. using System.IO;
  4. using System.ServiceModel;
  5. using System.ServiceModel.Web;
  6. using System.Text;
  7. using FrameworkBench;
  8. using Revenj.Api;
  9. using Revenj.DomainPatterns;
  10. using Revenj.Serialization;
  11. using Revenj.Utility;
  12. namespace Revenj.Bench
  13. {
  14. [ServiceContract(Namespace = "https://github.com/ngs-doo/revenj")]
  15. public interface IRestService
  16. {
  17. [OperationContract]
  18. [WebGet(UriTemplate = "/plaintext")]
  19. [Description("Plain text response")]
  20. Stream PlainText();
  21. [OperationContract]
  22. [WebGet(UriTemplate = "/json")]
  23. [Description("JSON response")]
  24. Stream JSON();
  25. [OperationContract]
  26. [WebGet(UriTemplate = "/db")]
  27. [Description("Single database query")]
  28. Stream SingleQuery();
  29. [OperationContract]
  30. [WebGet(UriTemplate = "/queries/{count}")]
  31. [Description("Multiple database queries")]
  32. Stream MultipleQueries(string count);
  33. [OperationContract]
  34. [WebGet(UriTemplate = "/updates/{count}")]
  35. [Description("Database updates")]
  36. Stream Updates(string count);
  37. }
  38. public class RestService : IRestService
  39. {
  40. private static readonly ChunkedMemoryStream HelloWorld = ChunkedMemoryStream.Static();
  41. private static readonly string[] IDs = new string[10001];
  42. [ThreadStatic]
  43. private static Context Context;
  44. private static Context GetContext(IServiceProvider services)
  45. {
  46. if (Context == null)
  47. Context = new Context(services);
  48. Context.Stream.Reset();
  49. return Context;
  50. }
  51. static RestService()
  52. {
  53. var hwText = Encoding.UTF8.GetBytes("Hello, World!");
  54. HelloWorld.Write(hwText, 0, hwText.Length);
  55. HelloWorld.Position = 0;
  56. for (int i = 0; i < IDs.Length; i++)
  57. IDs[i] = i.ToString();
  58. }
  59. private Random Random = new Random(0);
  60. private readonly IServiceProvider Services;
  61. public RestService(IServiceProvider services)
  62. {
  63. this.Services = services;
  64. }
  65. public Stream PlainText()
  66. {
  67. ThreadContext.Response.ContentType = "text/plain";
  68. return HelloWorld;
  69. }
  70. private Stream ReturnJSON(IJsonObject value, ChunkedMemoryStream cms)
  71. {
  72. value.Serialize(cms);
  73. ThreadContext.Response.ContentType = "application/json";
  74. return cms;
  75. }
  76. public Stream JSON()
  77. {
  78. var ctx = GetContext(Services);
  79. return ReturnJSON(new Message { message = "Hello, World!" }, ctx.Stream);
  80. }
  81. public Stream SingleQuery()
  82. {
  83. var id = Random.Next(10000) + 1;
  84. var ctx = GetContext(Services);
  85. var world = ctx.Repository.Find(IDs[id]);
  86. return ReturnJSON(world, ctx.Stream);
  87. }
  88. private void LoadWorlds(int repeat, Context ctx)
  89. {
  90. var reader = ctx.BulkReader;
  91. var lazyResult = ctx.LazyWorlds;
  92. var worlds = ctx.Worlds;
  93. reader.Reset(true);
  94. for (int i = 0; i < repeat; i++)
  95. {
  96. var id = Random.Next(10000) + 1;
  97. lazyResult[i] = reader.Find<World>(IDs[id]);
  98. }
  99. reader.Execute();
  100. for (int i = 0; i < repeat; i++)
  101. worlds[i] = lazyResult[i].Value;
  102. }
  103. public Stream MultipleQueries(string count)
  104. {
  105. int repeat;
  106. int.TryParse(count, out repeat);
  107. if (repeat < 1) repeat = 1;
  108. else if (repeat > 500) repeat = 500;
  109. var ctx = GetContext(Services);
  110. LoadWorlds(repeat, ctx);
  111. var cms = ctx.Stream;
  112. ctx.Worlds.Serialize(cms, repeat);
  113. ThreadContext.Response.ContentType = "application/json";
  114. return cms;
  115. }
  116. private static readonly Comparison<World> ASC = (l, r) => l.id - r.id;
  117. public Stream Updates(string count)
  118. {
  119. int repeat;
  120. int.TryParse(count, out repeat);
  121. if (repeat < 1) repeat = 1;
  122. else if (repeat > 500) repeat = 500;
  123. var ctx = GetContext(Services);
  124. LoadWorlds(repeat, ctx);
  125. var result = new World[repeat];
  126. Array.Copy(ctx.Worlds, result, repeat);
  127. for (int i = 0; i < result.Length; i++)
  128. result[i].randomNumber = Random.Next(10000) + 1;
  129. Array.Sort(result, ASC);
  130. ctx.Repository.Update(result);
  131. var cms = ctx.Stream;
  132. result.Serialize(cms);
  133. ThreadContext.Response.ContentType = "application/json";
  134. return cms;
  135. }
  136. }
  137. }