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
2
search-learn 20 grudzień 2019, 05:28

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.

0
Community 20 czerwiec 2020, 12:12