it-swarm.dev

AWS Step Function - Tunggu hingga acara

Saya memiliki kasus penggunaan di mana saya memiliki fungsi AWS Step yang dipicu ketika file diunggah ke S3, dari sana langkah pertama menjalankan ffprobe untuk mendapatkan durasi file dari layanan eksternal seperti transloadit di mana output ditulis kembali ke S3.

Saya dapat membuat fungsi langkah baru dari acara itu, tetapi saya berkeliaran jika mungkin untuk memiliki janji Tunggu di dalam fungsi langkah asli dan kemudian melanjutkan ke yang berikutnya - dengan mempertimbangkan bahwa mungkin diperlukan waktu lebih lama untuk proses kembali.

Saran apa pun sangat dihargai tentang cara mengatasi hal ini.

9
khinester

Tidak dapat mengusulkan solusi sederhana, hanya beberapa arahan untuk dijelajahi.

Pertama, Fungsi Langkah memiliki cara khusus untuk menangani pekerjaan latar belakang yang berjalan lama: aktivitas. https://docs.aws.Amazon.com/step-functions/latest/dg/concepts-activities.html ini pada dasarnya adalah antrian.

Jika Anda ingin 100% serverless, ini akan menjadi rumit atau jelek.

  • baik, seperti yang Anda katakan, buat fungsi langkah baru untuk setiap file
  • atau, loop jajak pendapat S3 di mesin negara menggunakan kode kesalahan khusus dan klausa Retry

Jika Anda dapat mengalokasikan instance "1/8 mikro" untuk pekerja latar belakang, itu tidak elegan namun mudah dan dapat diimplementasikan dengan reaksi instan. Petunjuk persyaratan perangkat keras yang rendah bahwa kita akan menggunakan mesin hanya untuk sinkronisasi.

Tentukan aktivitas StepFunction, misalnya bernama video-duration. Tetapkan antrian SQS untuk reaksi instan atau polling S3 untuk hasil durasi.

Status pseudocode fungsi:

{
  StartAt: ffprobe
  ffprobe: {
    Type: Task
    Resource: arn:...lambda:launch-ffprobe
    Next: wait-duration
  }
  wait-duration: {
    Type: Task
    Resource: arn...activity:video-duration
    End: true
  }
}

Pseudocode pekerja latar belakang:

statemap = dict/map filename to result

thread1:
  loop:
    taskToken, input = SF.GetActivityTask('video-duration')  # long poll
    sync(key=input.filename, waiter=taskToken)
thread2:
  loop:
    msg = SQS.ReceiveMessage(...)  # or poll S3
    sync(key=msg.filename, duration=msg.result)

function sync(key, waiter, duration):
  state = statemap[key]
  if waiter:
    state.waiter = waiter
  if duration:
    state.duration = duration
  if state.waiter and state.duration:
    SF.SendTaskSuccess(state.waiter, state.duration)

Pseudocode pemicu S3:

if filename is video:
  SF.StartExecution(...)
else if filename is duration:
  content = S3.GetObject(filename)
  SQS.SendMessage(queue, content)
1
temoto

Saat Anda mengirim permintaan untuk transloadit, simpan taskToken untuk langkah dalam s3 di kunci yang dapat diprediksi berdasarkan pada kunci file yang diunggah. Misalnya, jika file media di 's3: //my-media-bucket/foobar/media-001.mp3', Anda bisa membuat file JSON yang berisi token tugas dari langkah saat ini dan menyimpannya dengan kunci yang sama dalam keranjang yang berbeda, misalnya 's3: //ffprobe-tasks/foobar/media-001.mp3.json'. Pada akhir langkah Anda yang mengirim media ke transloadit jangan panggil kesuksesan atau kegagalan pada langkah - biarkan berjalan.

Kemudian ketika Anda mendapatkan pemberitahuan s3 bahwa hasil transloadit siap, Anda dapat menentukan kunci s3 untuk mendapatkan token tugas ('s3: //ffprobe-tasks/foobar/media-001.mp3'), muat JSON (dan hapus dari s3) dan kirim sukses untuk tugas itu. Fungsi langkah akan melanjutkan ke status berikutnya dalam eksekusi.

1
ivo

saya juga membahas masalah ini, ketika saya mencoba menggabungkan SFN untuk mengatur pekerjaan AWS Batch. praktik yang disarankan di atas bermasalah, karena Anda harus melewati taskToken, jadi Anda perlu, dari lambda inside state-machine, untuk polling TaskToken dari antrian, dan meneruskannya ke S3 atau di suatu tempat, yang lambda lain akan kirimkan status aktivitas.

masalahnya adalah: ketika Anda polling taskToken, Anda tidak bisa tahu apakah itu milik instance mesin-negara Anda. Anda bisa mendapatkan token pada instance lain dari sate-machine yang sama. secara pribadi, saya pikir akan lebih baik jika AWS akan mendukung fungsionalitas ini, yang dengan mudah dapat mereka lakukan ...

0
RELW

Yah, saya akan menginspirasi diri saya dari https://aws.Amazon.com/blogs/compute/implementing-serverless-manual-approval-steps-in-aws-step-functions-and-Amazon-api-gateway/

Anda dapat mengganti API Gateway dalam fungsi ini dengan fungsi AWS Lambda, dipicu oleh acara S3 misalnya (Dokumentasi: http://docs.aws.Amazon.com/lambda/latest/dg/with-s3.html ). Pastikan Tugas Anda memiliki batas waktu yang sesuai.

0
ElFitz

Anda umumnya ingin memulai tugas asinkron sebagai aktivitas Fungsi Langkah. Kata kunci di sini adalah memulai - dengan kata lain, begitu aktivitas Anda memiliki tindakan yang tertunda, saat itulah Anda memicu tindakan asinkron Anda. Alasannya adalah karena Anda memerlukan token tugas yang terkait dengan aktivitas yang tertunda - maka selama "masa depan" Anda dapat menyertakan token ini entah bagaimana (misalnya Anda dapat menetapkannya sebagai referensi atau ID permintaan), maka Anda dapat "menyelesaikan" aktivitas dengan sukses atau gagal menggunakan SendTaskSuccess atau SendTaskFailure panggilan.

Ada dua pendekatan untuk memulai tugas:

  1. Jajak pendapat untuk aktivitas baru. Anda akan mengatur acara terjadwal CloudWatch untuk membuat GetActivityTask menelepon setiap n menit.

  2. Menjalankan tugas "inisiator" baru secara paralel dengan aktivitas Anda dalam fungsi langkah. Inisiator ini melakukan hal yang sama seperti # 1 dan membuat panggilan GetActivityTask, satu-satunya perbedaan adalah ia dipicu segera dan tidak memerlukan mekanisme pemungutan suara. Panggilan GetActivityTask memblokir hingga tugas aktivitas baru tersedia, sehingga tidak ada masalah dengan kondisi ras. Perhatikan ada kemungkinan Anda dapat mengambil suatu kegiatan dari eksekusi lain, sehingga inisiator ini hanya perlu mempertimbangkan input dari aktivitas dan bukan input yang diterima inisiator itu sendiri.

Berikut adalah apa yang tampak seperti # 2 dalam Fungsi Langkah:

 Initiating an activity

Dan contoh kode dasar yang terkait dengan InitiateManualApprovalActivity tugas:

import boto3
import time

client = boto3.client('stepfunctions')
activity = "arn:aws:states:us-east-1:123456789012:activity:ManualStep"

def lambda_handler(event, context):
    print(event)
    # This will block until an activity task becomes available
    task = client.get_activity_task(activityArn=activity, workerName="test")
    print(task)
    # Perform your task here
    # In this example we continue on in the same function,
    # but the continuation could be a separate event, 
    # just as long as you can retrieve the task token
    time.sleep(60)
    response = client.send_task_success(taskToken=task['taskToken'], output=task['input'])
    print(response)
    return "done"
0
mixja