Mam funkcję wyzwalaną przez HTTP w mojej aplikacji funkcji - jest ona wywoływana przez łącznik elementu webhook w Azure Logic Apps. Sposób, w jaki webhooki działają w Logic Apps, polega na tym, że potrzebują one początkowej odpowiedzi, takiej jak "status:200"
, która usypia aplikację Logic, a po zakończeniu „pracy” wywoływana jest callbackURL
, a następnie aplikacja Logic wznawia działanie . Mój problem polega na wysłaniu tej początkowej odpowiedzi z mojej aplikacji funkcji.
Jeśli nie odpowiesz na webhooka ze statusem: 2 ** w ciągu 2 minut, wtedy webhook „ponowi próbę”, co uruchamia nową instancję aplikacji funkcji i jest to oczywiście problematyczne.
Więc mój kod wygląda mniej więcej tak
try
{
await function1() // this function runs more than 2 minutes
}
catch(err)
{
context.log(err)
}
finally
{
await function2() // this function returns to LogicApp via callbackurl
}
Próbowałem dodać context.res = { status:200}
w bloku try i próbowałem utworzyć indywidualną funkcję, która ma w środku context.res = {status:200}
, jednak żadna z nich nie działa.
Jeśli moja funkcja działa poniżej 2 minut, to oczywiście webhook nie ponawia próby, jednak jeśli trwa to dłużej niż 2 minuty, kończy się niepowodzeniem.
Próbowałem budować w oparciu o projekt „Webhook” z tego artykułu
Wywołanie długotrwałych funkcji Azure
Oto kombinacje, które wypróbowałem:
try {
context.bindings.res = {status:202}
await function1()
}
try {
context.res = {status:202}
await function1()
}
try {
await initialResponse(context)// function that has context.res={status:202} inside
function1()
}
try {
context.res = {status:202}
context.done()
await function1()
} // I added @UncleDave 's suggestion as well
try {
await initialResponse(context)
function1()
}
async function initialResponse(context)
{
context.res = {status:202}
context.done()
} // this attempt also just ended the function
1 odpowiedź
Zastanów się nad utworzeniem drugiej funkcji do obsługi długotrwałej operacji i zmień bieżącą funkcję tak, aby przerzuciła żądanie do kolejki i natychmiast wróciła.
Wyzwalacz HTTP trafiony przez Twój hak sieciowy:
function.json
{
"bindings": [
{
"authLevel": "anonymous", // Don't do this - demonstration only.
"type": "httpTrigger",
"direction": "in",
"name": "req",
"methods": [
"post"
]
},
{
"type": "http",
"direction": "out",
"name": "res"
},
{
"type": "queue",
"direction": "out",
"name": "queue",
"queueName": "process",
"connection": "AzureWebJobsStorage"
}
]
}
index.js
module.exports = function (context, req) {
context.log('Started processing a request.', req);
context.done(null, {
res: { status: 202 },
queue: { callbackUrl: req.body.callbackUrl, data: req.body.data }
});
};
Wyzwalacz kolejki, który wykonuje przetwarzanie:
function.json
{
"bindings": [
{
"name": "item",
"type": "queueTrigger",
"direction": "in",
"queueName": "process",
"connection": "AzureWebJobsStorage"
}
]
}
index.js
module.exports = async function (context, item) {
context.log('JavaScript queue trigger function started to process work item.', item);
const data = await process(item.data);
const request = require('request');
await request.post(item.callbackUrl, { body: data, json: true });
};
function process(data) {
// Some long running operation.
return new Promise(resolve => {
setTimeout(() => resolve({ a: 'b', c: 'd' }), 5000);
});
}
Zauważ, że używam tutaj request
, co jest zewnętrzną zależnością, którą musisz dodać do swojego package.json
, ale wbudowany klient HTTP Node będzie działał równie dobrze.
Podobne pytania
Nowe pytania
node.js
Node.js to oparte na zdarzeniach, nieblokujące, asynchroniczne środowisko wykonawcze we / wy, które korzysta z silnika JavaScript V8 firmy Google i biblioteki libuv. Służy do tworzenia aplikacji, które w dużym stopniu wykorzystują możliwość uruchamiania JavaScript zarówno po stronie klienta, jak i po stronie serwera, a zatem korzystają z możliwości ponownego wykorzystania kodu i braku przełączania kontekstów.