Azure Functions のプリコンパイルサポート

.NETなFunctionsの場合、プリコンパイルがサポートされました。簡単にいうと.csxじゃなくてコンパイル済みアセンブリ(.dll)を指定することで動的コンパイル処理をスキップすることができるようになりました。

https://twitter.com/hutchcodes/status/817124237576118276

 

やりかた

function.json に2つのプロパティを追加するだけです。

例:

{
    "scriptFile": "PreCompiledFunctionSample.dll",
    "entryPoint": "PreCompiledFunctionSample.MyFunction.Run",
    "bindings": [
        {
            "authLevel": "function",
            "name": "req",
            "type": "httpTrigger",
            "direction": "in"
        },
        {
            "name": "$return",
            "type": "http",
            "direction": "out"
        }
    ],
    "disabled": false
}

scriptFile に実行する関数が含まれているアセンブリのファイルを、entryPointに実行するメソッドを指定します。entryPointはだいたいは 名前空間.クラス名.メソッド名 という形式になるかと思います。

後はfunction.jsonと対象のアセンブリだけ放り込めばコンパイル処理はスキップされて実行されます。

サンプルプロジェクトがあるのでこちらで試してみましょう。

  • azfunc-precompiled-sample
  • ※Issue+PRはしたのですがそのままだとビルドできませんので、NuGetで Microsoft.AspNet.WebApi.Core を追加してください。

出来上がったらAzure Functionsに登録します。(フォルダ作ってDLLとfunction.jsonをUploadするだけです)
image

実行してみると問題なく処理されてますね。
image

注意点

どうもアセンブリがどこかで持ったままになってる感。アセンブリ入れ替え時うまく入れ替わらない・削除できないなどが発生した場合はApp Service再起動したり(Kuduからw3wp.exeをKillしたり)しましょう。

デバッグとか

ローカルにはソースがあるわけですから、もちろんリモートデバッグもできます。(やり方は以前のPost参照)

まとめ

アセンブリにできるおかげでフルのインテリセンス使った開発もできますし、ローカル開発含めて柔軟性が広がったんではないでしょうか。起動時の余分な処理も飛ばせますし、良い改善だと思います。

 

おまけ

VB.NETでもできるか試してみました。けど、うまく動きませんでした。認識はしてくれてる見たいなんですが、実行時に

 Exception while executing function: Functions.VB3. Microsoft.VisualBasic: Public member 'name' on type 'JObject' not found

とかいうエラーになって500 Internal Server Error になってしまいます。なぞい。ちなみにVB.NETのコードはこんな感じです。(Option Strict Off消したら動きました。VB力低くてすみません)

Imports System.Net
Imports System.Net.Http

Public Class Class1
    Public Shared Async Function Run(ByVal req As HttpRequestMessage) As Task(Of HttpResponseMessage)
        Dim name = req.GetQueryNameValuePairs().FirstOrDefault(Function(q) String.Compare(q.Key, "name", True) = 0).Value

        If (name IsNot Nothing) Then
            Return req.CreateResponse(HttpStatusCode.OK, "VB.NET Hello " + name)
        End If

        Return req.CreateResponse(HttpStatusCode.BadRequest, "Please pass a name on the query string or in the request body")

    End Function
End Class

vbfunctions

ちゃんと動きましたとさ。

例外みるとこんな感じです。

...obs.Script.Description.FunctionInvokerBase.<Invoke>d__29.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionInvoker`1.<InvokeAsync>d__8.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<InvokeAsync>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithWatchersAsync>d__21.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__19.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd(Task task)
   at Microsoft.Azure.WebJobs.Host.Executors.FunctionExecutor.<ExecuteWithLoggingAsync>d__13.MoveNext()
   --- End of inner exception stack trace ---

縄神様が解決してくれることを願っております。。

Azure Functions のプリコンパイルサポート」への1件のフィードバック

  1. ピンバック: Azure Update (2017.01.12) | ブチザッキ

コメントを残す