Skip to content
This repository has been archived by the owner on Dec 15, 2021. It is now read-only.

.NET Core runtime major fixes #697

Merged

Conversation

allantargino
Copy link
Contributor

@allantargino allantargino commented Apr 14, 2018

Issue Ref: fixes #395, fixes #688 and refs #451.

Description: , I fixed the errors with liveness probe in .NET Core runtime. Also, added the possibility to use custom dependencies. Really helped the dev guide in #671. There are many other improvements regarding code and performance (function DLL cache at startup time). Tests for .NET Core were enabled again.

To start using, you should just use dotnet cli:

dotnet new library

Generating both files:

  • something.cs (function)
  • something.csproj (dependencies)

To add dependencies:

dotnet add package PackageName

Using in kubeless:

kubeless function deploy --from-file something.cs --handler module.handler --runtime dotnetcore2.0 --dependencies something.csproj myfunction

TODOs:

  • Ready to review
  • Automated Tests
  • Implement all features from other runtimes
  • Examples

@allantargino
Copy link
Contributor Author

Great thanks to @mgernand, who actually gave the idea of dotnet new library, genius :)

@allantargino
Copy link
Contributor Author

@mgernand, sorry for taking so long to go back to the project. We were working on CSELATAM/kubeless-netcore-runtime, but it's better for us to work directly here. When you have the time, I would appreciate your ideas and code on this new version!

@allantargino
Copy link
Contributor Author

allantargino commented Apr 14, 2018

hi kubeless team, I don't know if I activate all the tests for .NET Core - if don't, just let me know!
I can squash the commits as soon as you think it's ready for merge.

@andresmgot
Copy link
Contributor

andresmgot commented Apr 16, 2018

Hi @allantargino, thanks for working on this and fixing the integration test!

Before moving on with the support of .NET and to make sure it has the same features than the rest of runtimes: Could you confirm that the server fulfill the following requirements? (I marked the items which I think the runtime already satisfies).

  • The function to load can be specified using an environment variable MOD_NAME.
  • The function to load can be specified using an environment variable FUNC_HANDLER.
  • The port used to expose the service can be modified using an environment variable FUNC_PORT.
  • The server should return 200 - OK to requests at /healthz.
  • Functions should run FUNC_TIMEOUT as maximum.
  • Functions should receive two parameters: event and context and should return the value that will be used as HTTP response.
  • Requests should be served in parallel.
  • Requests should be logged to stdout including date, HTTP method, requested path and status code of the response.
  • Exceptions in the function should be caught. The server should not exit due to a function error.

If you have any question regarding the above items don't hesitate to ask. Once the above has been completed we can help you enabling the standard end-to-end tests that ensure some of those items.

@allantargino
Copy link
Contributor Author

allantargino commented Apr 29, 2018

Hi @andresmgot !

Great, totally make sense to catch up the other features presents on all other runtimes. I checked some other items that already were satisfied as well.

I'll be working on the next features then. On the future, I'll probably use the strategy adopted in go-lang runtime, using compilation :) (great ideia!)

  • The function to load can be specified using an environment variable MOD_NAME.
  • The function to load can be specified using an environment variable FUNC_HANDLER.
  • The port used to expose the service can be modified using an environment variable FUNC_PORT.
  • The server should return 200 - OK to requests at /healthz.
  • Functions should run FUNC_TIMEOUT as maximum.
  • Functions should receive two parameters: event and context and should return the value that will be used as HTTP response.
  • Requests should be served in parallel.
  • Requests should be logged to stdout including date, HTTP method, requested path and status code of the response.
  • Exceptions in the function should be caught. The server should not exit due to a function error.

Thanks!

@andresmgot
Copy link
Contributor

hi @allantargino, happy to see this close to a checklist fully fulfilled :) let us know if you have any problem with that or the tests

@andresmgot andresmgot mentioned this pull request May 15, 2018
3 tasks
@allantargino
Copy link
Contributor Author

Hi @andresmgot ! Thanks for the support 👍
After some while, I believe .NET Core runtime has checked all items on the list! It definitely makes total sense to require that from every runtime on Kubeless.

@allantargino
Copy link
Contributor Author

Now, the injection of Event and Context really helps the user to create unit tests in a isolate environment from kubernetes:

using System;
using Kubeless.Functions;

public class hellowithdata
{
    public object handler(Event k8Event, Context k8Context)
    {
        return k8Event.Data;
    }
}

The main code of the runtime can be summarized on this controller:

using Kubeless.Core.Interfaces;
using Kubeless.Functions;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Threading;

namespace Kubeless.WebAPI.Controllers
{
    [Route("/")]
    public class RuntimeController : Controller
    {
        private readonly IFunction _function;
        private readonly IParameterHandler _parameterManager;
        private readonly IInvoker _invoker;

        public RuntimeController(IFunction function, IParameterHandler parameter, IInvoker invoker)
        {
            _function = function;
            _invoker = invoker;
            _parameterManager = parameter;
        }

        [AcceptVerbs("GET", "POST", "PUT", "PATCH", "DELETE")]
        public object Execute()
        {
            Console.WriteLine("{0}: Function Started. HTTP Method: {1}, Path: {2}.", DateTime.Now.ToString(), Request.Method, Request.Path);

            try
            {
                (Event _event, Context _context) = _parameterManager.GetFunctionParameters(Request);

                CancellationTokenSource _cancellationSource = new CancellationTokenSource();

                var output = _invoker.Execute(_function, _cancellationSource, _event, _context);

                Console.WriteLine("{0}: Function Executed. HTTP response: {1}.", DateTime.Now.ToString(), 200);
                return output;
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("{0}: Function Cancelled. HTTP Response: {1}. Reason: {2}.", DateTime.Now.ToString(), 408, "Timeout");
                return new StatusCodeResult(408);
            }
            catch (Exception ex)
            {
                Console.WriteLine("{0}: Function Corrupted. HTTP Response: {1}. Reason: {2}.", DateTime.Now.ToString(), 500, ex.Message);
                throw;
            }
        }

        [HttpGet("/healthz")]
        public IActionResult Health() => Ok();

    }
}

@allantargino
Copy link
Contributor Author

And a Nuget package was published as well:
https://www.nuget.org/packages/Kubeless.Functions/
I will include that on docs later, but the user can easily use dotnet tools to start developing for kubeless:

dotnet new library
dotnet add package Kubeless.Functions

@andresmgot
Copy link
Contributor

Hi @allantargino, this is great, thank you for working on this!

I just have a bit more of feedback:

  • I see that it is always necessary to specify a .cssproj for adding the Kubeless.Functions package. Can you add that to the base image so it is not necessary to specify the flag --dependencies every time? That is useful for environments like the GUI in which people only deploy a function.
  • Can you add a few lines in docs/runtimes.md about the new runtime?
  • If you implement the first point and the --dependencies flag is not necessary, can you add the dotnetcore/dependency-yaml.cs example to the examples/Makefile so you can add it as a test as well in tests/integration-tests.bats?

Once that is ready we can merge this PR :)

@allantargino
Copy link
Contributor Author

allantargino commented May 18, 2018

Hi @andresmgot!
I just fixed the mentioned points.

  • Now, a function that doesn't have any other external requirement than Kubeless.Functions package, doesn't require the flag --dependencies.
  • Docs updated
  • dotnetcore/dependency-yaml.cs exampled added to examples/Makefile and called at tests/integration-tests.bats

@allantargino
Copy link
Contributor Author

But for some reason I could identify most of the tests are failing now - seems to be something during the creation of some components in the cluster. Can you help me please @andresmgot ?

@andresmgot
Copy link
Contributor

andresmgot commented May 18, 2018

The problem was that there were spaces instead of a tab in the Makefile :) should be fixed now.

@andresmgot
Copy link
Contributor

Now everything has been completed (we can ignore the Travis error). Thank you again @allantargino 🎉

@andresmgot andresmgot merged commit 473f2e2 into vmware-archive:master May 18, 2018
@allantargino
Copy link
Contributor Author

That's great! Thanks for helping me @andresmgot 👍

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
2 participants