Skip to content

Commit 1ee8422

Browse files
authored
Adding FunctionsNetHost native component (#1212)
* ⚽ Adding FunctionsNetHost bits * Cleanup * adding nuspec * ReadME improvements.
1 parent e06ba26 commit 1ee8422

37 files changed

+2176
-0
lines changed

host/.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.vs/
2+
build/
3+
out/
4+
.idea/
5+
cmake-build-*/
6+
/src/.idea/

host/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# FunctionsNetHost
2+
3+
[![Build Status](https://azfunc.visualstudio.com/Azure%20Functions/_apis/build/status/fabiocav.net-worker-host?branchName=main)](https://azfunc.visualstudio.com/Azure%20Functions/_build/latest?definitionId=201&branchName=main)
4+
5+
FunctionsNetHost is a native component which enables placeholder mode & specialization for dotnet isolated function apps.
6+
7+
## Build
8+
9+
[Build - Windows](docs/build.md)

host/azure-pipelines.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
variables:
2+
- name: VCPKG_BINARY_SOURCES
3+
value: 'clear;nuget,https://azfunc.pkgs.visualstudio.com/e6a70c92-4128-439f-8012-382fe78d6396/_packaging/FunctionsNetHostBinaryCache/nuget/v3/index.json,readwrite'
4+
- name: VCPKG_USE_NUGET_CACHE
5+
value: 1
6+
7+
trigger:
8+
branches:
9+
include:
10+
- main
11+
- release/*
12+
paths:
13+
include:
14+
- host/src/
15+
pr:
16+
branches:
17+
include:
18+
- main
19+
- release/*
20+
paths:
21+
include:
22+
- host/src/
23+
24+
pool:
25+
vmImage: windows-latest
26+
27+
steps:
28+
# Remember to add this task to allow vcpkg to upload archives via NuGet
29+
- task: NuGetAuthenticate@1
30+
31+
# Will remove after validating builds are working.
32+
- script: dir
33+
workingDirectory: $(Build.SourcesDirectory)
34+
displayName: List Build.SourcesDirectory content
35+
36+
# Run Cmake and output goes to /build dir.
37+
- task: CMake@1
38+
displayName: 'CMake ..'
39+
timeoutInMinutes: 120
40+
inputs:
41+
cmakeArgs: '-S $(Build.SourcesDirectory)/host/src -B $(Build.SourcesDirectory)/host/build/win-x64'
42+
43+
# Run Cmake --build which produces the release artifacts
44+
- task: CMake@1
45+
displayName: 'CMake --build . --config Release'
46+
inputs:
47+
cmakeArgs: '--build $(Build.SourcesDirectory)/host/build/win-x64 --config Release --verbose'
48+
49+
- script: dir
50+
workingDirectory: $(Build.SourcesDirectory)/host/build/win-x64/FunctionsNetHost/Release
51+
displayName: List Release Artifacts
52+
53+
# Publish artifacts
54+
- publish: $(Build.SourcesDirectory)/host/build/win-x64/FunctionsNetHost/Release
55+
artifact: drop

host/docs/build.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# Build
2+
3+
Follow below instructions to build and develop locally.
4+
5+
## Quick Start: Windows
6+
7+
### Prerequisites
8+
9+
10+
* [CMake](https://cmake.org/download/) is our build system. Install version 3.23 or above.
11+
* _If you are new to CMake, [Modern CMake for C++](https://learning.oreilly.com/library/view/modern-cmake-for/9781801070058/) is great book to start with._
12+
* Visual Studio 2022 or above with [Desktop development with C++ workload](https://learn.microsoft.com/en-us/cpp/build/vscpp-step-0-installation?view=msvc-170).
13+
* [Git](https://git-scm.com/downloads)
14+
15+
## Build
16+
17+
1. Clone the [dotnet-worker](https://github.com/Azure/azure-functions-dotnet-worker) repo.
18+
2. Open a new instance of Visual Studio. Select "Open a local folder".
19+
3. Select the "host/src" directory.
20+
21+
Once VS opens this directory it will detect it as a CMake project and will execute the CMake command. You can see the output of this operation in the "Output" window. Once this step is done, you should see "CMake generation finished." log entry in the output window.
22+
23+
## Package management
24+
25+
We use [vcpkg](https://vcpkg.io/en/index.html) as our package manager. vcpkg downloads the source code of our dependencies, build the source locally and use the binaries. If you are running CMake for the first time in your machine, this process will take quite sometime to finish. vcpkg caches the output of this process locally so that subsequent CMake generation step will be using the built binaries from cache and thus build will be faster.
26+
27+
## Debugging
28+
29+
Visual studio supports F5 debugging for CMake/C++ projects. You should be able to put breakpoints in the code and inspect.
30+
31+
## Formatting
32+
33+
We have a .clang-format file in the root which uses the "Microsoft" based formatting styles. In visual studio, you can use the key combination of CTRL + K + D to format a document.
34+
35+
## Visual Studio Code
36+
37+
To build the binaries after code change, Run the below commands.
38+
39+
```
40+
// Create a directory which we will use for building.
41+
>mkdir -p build\win-x64
42+
43+
> cd build\win-x64
44+
45+
// Execute CMake command, specify source directory as 2 directories back of the current directory. build tree directory as current directory.
46+
> CMAKE -S ../../ -B .
47+
48+
// Once this step is done, you should see "Generating done" message in the terminal.
49+
50+
// Run cmake --build command which builds the binaries. Specify "Release" configuration using the --config flag.
51+
52+
> CMAKE --build . --config Release
53+
54+
```

host/src/.clang-format

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Language: Cpp
2+
BasedOnStyle: Microsoft

host/src/CMakeLists.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# CMakeList.txt : Top-level CMake project file, do global configuration
2+
# and include sub-projects here.
3+
#
4+
cmake_minimum_required (VERSION 3.23)
5+
6+
include(FetchContent)
7+
FetchContent_Declare(vcpkg
8+
GIT_REPOSITORY https://github.com/microsoft/vcpkg/
9+
GIT_TAG 2022.11.14
10+
)
11+
FetchContent_MakeAvailable(vcpkg)
12+
13+
# NOTE: This must be defined before the first project call
14+
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")
15+
16+
set(VCPKG_INSTALL_OPTIONS "--debug")
17+
18+
string(TIMESTAMP CURRENT_TIME "%m%d%H%M")
19+
# May replace with git commit id once hooked up to GH actions.
20+
project ("FunctionsNetHost" VERSION 0.0.0.${CURRENT_TIME})
21+
set(CMAKE_CXX_STANDARD 20)
22+
23+
# Include sub-projects.
24+
add_subdirectory("Protos")
25+
add_subdirectory ("FunctionsNetHost")
26+
add_subdirectory("funcgrpc")
27+
28+
configure_file(appconfig.h.in appconfig.h)
29+
30+
target_include_directories(FunctionsNetHost PUBLIC
31+
"${PROJECT_BINARY_DIR}"
32+
)

host/src/CMakePresets.json

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
{
2+
"version": 3,
3+
"configurePresets": [
4+
{
5+
"name": "windows-base",
6+
"hidden": true,
7+
"generator": "Ninja",
8+
"binaryDir": "${sourceDir}/out/build/${presetName}",
9+
"installDir": "${sourceDir}/out/install/${presetName}",
10+
"cacheVariables": {
11+
"CMAKE_C_COMPILER": "cl.exe",
12+
"CMAKE_CXX_COMPILER": "cl.exe"
13+
},
14+
"condition": {
15+
"type": "equals",
16+
"lhs": "${hostSystemName}",
17+
"rhs": "Windows"
18+
}
19+
},
20+
{
21+
"name": "x64-debug",
22+
"displayName": "x64 Debug",
23+
"inherits": "windows-base",
24+
"architecture": {
25+
"value": "x64",
26+
"strategy": "external"
27+
},
28+
"cacheVariables": {
29+
"CMAKE_BUILD_TYPE": "Debug"
30+
},
31+
"environment": {
32+
"Test": "test"
33+
}
34+
},
35+
{
36+
"name": "x64-release",
37+
"displayName": "x64 Release",
38+
"inherits": "x64-debug",
39+
"cacheVariables": {
40+
"CMAKE_BUILD_TYPE": "Release"
41+
}
42+
},
43+
{
44+
"name": "x86-debug",
45+
"displayName": "x86 Debug",
46+
"inherits": "windows-base",
47+
"architecture": {
48+
"value": "x86",
49+
"strategy": "external"
50+
},
51+
"cacheVariables": {
52+
"CMAKE_BUILD_TYPE": "Debug"
53+
}
54+
},
55+
{
56+
"name": "x86-release",
57+
"displayName": "x86 Release",
58+
"inherits": "x86-debug",
59+
"cacheVariables": {
60+
"CMAKE_BUILD_TYPE": "Release"
61+
}
62+
}
63+
]
64+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# CMakeList.txt : CMake project for FunctionsNetHost, include source and define
2+
# project specific logic here.
3+
#
4+
add_executable (FunctionsNetHost "main.cpp" "managedexports.cpp")
5+
target_link_libraries(FunctionsNetHost PRIVATE funcgrpc)
6+
7+
set_target_properties(FunctionsNetHost PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
8+
9+
if (CMAKE_VERSION VERSION_GREATER 3.12)
10+
set_property(TARGET FunctionsNetHost PROPERTY CXX_STANDARD 20)
11+
endif()
12+
13+
find_package(Boost REQUIRED COMPONENTS program_options)
14+
target_link_libraries(FunctionsNetHost PRIVATE Boost::program_options)
15+
16+
if(NOT TARGET spdlog)
17+
# Stand-alone build
18+
find_package(spdlog REQUIRED)
19+
endif()
20+
target_link_libraries(FunctionsNetHost PRIVATE spdlog::spdlog)

host/src/FunctionsNetHost/main.cpp

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the MIT License. See License.txt in the project root for license information.
3+
4+
#include "../funcgrpc/func_bidi_reactor.h"
5+
#include "../funcgrpc/func_perf_marker.h"
6+
#include "../funcgrpc/funcgrpc.h"
7+
#include "appconfig.h"
8+
#include <boost/program_options.hpp>
9+
#include <exception>
10+
#include <iostream>
11+
#include <limits.h>
12+
#include <string>
13+
14+
using namespace std;
15+
using namespace funcgrpc;
16+
namespace po = boost::program_options;
17+
18+
unique_ptr<funcgrpc::GrpcWorkerStartupOptions> getWorkerStartupOptions(int argc, char *const *argv);
19+
20+
int main(int argc, char *argv[])
21+
{
22+
funcgrpc::Log::Init();
23+
FUNC_LOG_INFO("Starting FunctionsNetHost main.Build:{}", FunctionsNetHost_VERSION);
24+
25+
try
26+
{
27+
auto pOptions = getWorkerStartupOptions(argc, argv);
28+
auto pApplication = std::make_unique<NativeHostApplication>();
29+
auto worker = std::make_unique<FunctionBidiReactor>(pOptions.get(), pApplication.get());
30+
Status status = worker->Await();
31+
32+
if (!status.ok())
33+
{
34+
FUNC_LOG_ERROR("Rpc failed. error_message:{}", status.error_message());
35+
}
36+
}
37+
catch (const std::exception &ex)
38+
{
39+
FUNC_LOG_ERROR("Caught unknown exception.{}", ex.what());
40+
}
41+
catch (...)
42+
{
43+
FUNC_LOG_ERROR("Caught unknown exception.");
44+
}
45+
46+
return 0;
47+
}
48+
49+
unique_ptr<GrpcWorkerStartupOptions> getWorkerStartupOptions(int argc, char *const *argv)
50+
{
51+
FuncPerfMarker marker("BuildWorkerStartupOptions");
52+
53+
po::options_description desc("Allowed options");
54+
desc.add_options()("help", "sample usage: FunctionsNetHost --host <endpoint> --port <port> --workerid <workerid> "
55+
"--requestid <requestid> --grpcmaxrequestlength <maxrequestlength>")(
56+
"host", boost::program_options::value<string>(),
57+
"Address of grpc server")("port", po::value<int>(), "Port number of grpc server connection")(
58+
"workerId", boost::program_options::value<string>(),
59+
"Worker id")("requestId", boost::program_options::value<string>(),
60+
"Request id")("grpcMaxMessageLength", po::value<int>()->default_value(INT_MAX),
61+
"Max length for grpc messages. Default is INT_MAX");
62+
63+
po::variables_map vm;
64+
po::store(po::parse_command_line(argc, argv, desc), vm);
65+
po::notify(vm);
66+
67+
auto options = make_unique<GrpcWorkerStartupOptions>();
68+
69+
if (vm.count("host"))
70+
{
71+
options->host = vm["host"].as<string>();
72+
}
73+
if (vm.count("port"))
74+
{
75+
options->port = vm["port"].as<int>();
76+
}
77+
if (vm.count("workerId"))
78+
{
79+
options->workerId = vm["workerId"].as<string>();
80+
}
81+
if (vm.count("requestId"))
82+
{
83+
options->requestId = vm["requestId"].as<string>();
84+
}
85+
if (vm.count("grpcMaxMessageLength"))
86+
{
87+
options->grpcMaxMessageLength = vm["grpcMaxMessageLength"].as<int>();
88+
}
89+
90+
return options;
91+
}

0 commit comments

Comments
 (0)