Async task (#25)
Support for async/await.
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<JObject> 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 @@
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 @@
{
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.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 @@
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 @@
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<JObject> 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 @@
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 @@
{
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.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 @@
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 @@
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 @@
{
return (args);
}
+
+ public async Task<JObject> 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 @@
}
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 @@
}
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 = {