.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するだけです)
注意点
どうもアセンブリがどこかで持ったままになってる感。アセンブリ入れ替え時うまく入れ替わらない・削除できないなどが発生した場合は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
ちゃんと動きましたとさ。
例外みるとこんな感じです。
...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 Update (2017.01.12) | ブチザッキ