diff --git a/core/dotnet2.2/CHANGELOG.md b/core/dotnet2.2/CHANGELOG.md index c530536..dfa57a4 100644 --- a/core/dotnet2.2/CHANGELOG.md +++ b/core/dotnet2.2/CHANGELOG.md @@ -23,3 +23,15 @@ ## 1.13 Changes: - Initial release + +## Release TBD +Changes: +- Support for async methods. Example: + +```csharp + public async Task MainAsync(JObject args) + { + await Task.Delay(10); // Just do a delay to have an async/await process occur. + return (args); + } +``` diff --git a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs index f5d9489..55a637f 100644 --- a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs +++ b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs @@ -33,6 +33,7 @@ public class Init private Type Type { get; set; } private MethodInfo Method { get; set; } private ConstructorInfo Constructor { get; set; } + private bool AwaitableMethod { get; set; } public Init() { @@ -51,7 +52,7 @@ public async Task HandleRequest(HttpContext httpContext) { await httpContext.Response.WriteError("Cannot initialize the action more than once."); Console.Error.WriteLine("Cannot initialize the action more than once."); - return (new Run(Type, Method, Constructor)); + return (new Run(Type, Method, Constructor, AwaitableMethod)); } string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync(); @@ -156,7 +157,9 @@ await httpContext.Response.WriteError(ex.Message await httpContext.Response.WriteResponse(200, "OK"); - return (new Run(Type, Method, Constructor)); + AwaitableMethod = (Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null); + + return (new Run(Type, Method, Constructor, AwaitableMethod)); } catch (Exception ex) { diff --git a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs index 1ee35bb..21c94f0 100644 --- a/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs +++ b/core/dotnet2.2/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs @@ -29,12 +29,14 @@ public class Run private readonly Type _type; private readonly MethodInfo _method; private readonly ConstructorInfo _constructor; + private readonly bool _awaitableMethod; - public Run(Type type, MethodInfo method, ConstructorInfo constructor) + public Run(Type type, MethodInfo method, ConstructorInfo constructor, bool awaitableMethod) { _type = type; _method = method; _constructor = constructor; + _awaitableMethod = awaitableMethod; } public async Task HandleRequest(HttpContext httpContext) @@ -79,7 +81,14 @@ await Console.Error.WriteLineAsync( try { - JObject output = (JObject) _method.Invoke(owObject, new object[] {valObject}); + JObject output; + + if(_awaitableMethod) { + output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject}); + } + else { + output = (JObject) _method.Invoke(owObject, new object[] {valObject}); + } if (output == null) { diff --git a/core/dotnet3.0/CHANGELOG.md b/core/dotnet3.0/CHANGELOG.md index 9339dd7..c09bde8 100644 --- a/core/dotnet3.0/CHANGELOG.md +++ b/core/dotnet3.0/CHANGELOG.md @@ -20,6 +20,15 @@ # .NET Core 3.0 OpenWhisk Runtime Container -## 1.14 (next Apache release) +## Release TBD Changes: - Initial release +- Support for async methods. Example: + +```csharp + public async Task MainAsync(JObject args) + { + await Task.Delay(10); // Just do a delay to have an async/await process occur. + return (args); + } +``` diff --git a/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs b/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs index f5d9489..55a637f 100644 --- a/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs +++ b/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Init.cs @@ -33,6 +33,7 @@ public class Init private Type Type { get; set; } private MethodInfo Method { get; set; } private ConstructorInfo Constructor { get; set; } + private bool AwaitableMethod { get; set; } public Init() { @@ -51,7 +52,7 @@ public async Task HandleRequest(HttpContext httpContext) { await httpContext.Response.WriteError("Cannot initialize the action more than once."); Console.Error.WriteLine("Cannot initialize the action more than once."); - return (new Run(Type, Method, Constructor)); + return (new Run(Type, Method, Constructor, AwaitableMethod)); } string body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync(); @@ -156,7 +157,9 @@ await httpContext.Response.WriteError(ex.Message await httpContext.Response.WriteResponse(200, "OK"); - return (new Run(Type, Method, Constructor)); + AwaitableMethod = (Method.ReturnType.GetMethod(nameof(Task.GetAwaiter)) != null); + + return (new Run(Type, Method, Constructor, AwaitableMethod)); } catch (Exception ex) { diff --git a/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs b/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs index 1ee35bb..21c94f0 100644 --- a/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs +++ b/core/dotnet3.0/proxy/Apache.OpenWhisk.Runtime.Common/Run.cs @@ -29,12 +29,14 @@ public class Run private readonly Type _type; private readonly MethodInfo _method; private readonly ConstructorInfo _constructor; + private readonly bool _awaitableMethod; - public Run(Type type, MethodInfo method, ConstructorInfo constructor) + public Run(Type type, MethodInfo method, ConstructorInfo constructor, bool awaitableMethod) { _type = type; _method = method; _constructor = constructor; + _awaitableMethod = awaitableMethod; } public async Task HandleRequest(HttpContext httpContext) @@ -79,7 +81,14 @@ await Console.Error.WriteLineAsync( try { - JObject output = (JObject) _method.Invoke(owObject, new object[] {valObject}); + JObject output; + + if(_awaitableMethod) { + output = (JObject) await (dynamic) _method.Invoke(owObject, new object[] {valObject}); + } + else { + output = (JObject) _method.Invoke(owObject, new object[] {valObject}); + } if (output == null) { diff --git a/tests/dotnetshared/Echo.cs b/tests/dotnetshared/Echo.cs index ba39177..29f1a33 100644 --- a/tests/dotnetshared/Echo.cs +++ b/tests/dotnetshared/Echo.cs @@ -17,6 +17,7 @@ using System; using Newtonsoft.Json.Linq; +using System.Threading.Tasks; namespace Apache.OpenWhisk.Tests.Dotnet { @@ -26,5 +27,11 @@ public JObject Main(JObject args) { return (args); } + + public async Task MainAsync(JObject args) + { + await Task.Delay(10); // Just do a delay to have an async/await process occur. + return (args); + } } } diff --git a/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala b/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala index 6f84f75..bea113b 100644 --- a/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala +++ b/tests/src/test/scala/actionContainers/DotNet2_2ActionContainerTests.scala @@ -52,7 +52,7 @@ class DotNet2_2ActionContainerTests extends BasicActionRunnerTests with WskActor } val testEchoNoWrite = { - TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Echo::Main") + TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Echo::MainAsync") } override val testUnicode = { diff --git a/tests/src/test/scala/actionContainers/DotNet3_0ActionContainerTests.scala b/tests/src/test/scala/actionContainers/DotNet3_0ActionContainerTests.scala index ec937ab..d05860c 100644 --- a/tests/src/test/scala/actionContainers/DotNet3_0ActionContainerTests.scala +++ b/tests/src/test/scala/actionContainers/DotNet3_0ActionContainerTests.scala @@ -52,7 +52,7 @@ class DotNet3_0ActionContainerTests extends BasicActionRunnerTests with WskActor } val testEchoNoWrite = { - TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Echo::Main") + TestConfig(functionb64, main = "Apache.OpenWhisk.Tests.Dotnet::Apache.OpenWhisk.Tests.Dotnet.Echo::MainAsync") } override val testUnicode = {