Guida pratica: Caricamento (avanzato)
Guida pratica: Caricamento (avanzato)
Introduzione
Il caricamento affidabile delle risorse è la funzione principale di ogni integrazione C2C. Questa guida fornisce tecniche avanzate e best practice per creare un sistema di caricamento affidabile, resiliente ed efficiente che funziona bene anche in ambienti complessi.
Prerequisiti
Se non l’hai già fatto, consulta la guida Implementazione C2C: configurazione prima di procedere. Avrai bisogno dell’access_token ottenuto durante il processo di autenticazione e autorizzazione. Useremo la stessa risorsa di test della guida sui caricamenti di base.
Parametri avanzati delle risorse
Quando crei delle risorse in Frame.io, puoi utilizzare diversi parametri avanzati per personalizzare le modalità di caricamento. Il parametro offset è particolarmente importante per un’integrazione corretta.
Offset - Gestione dei dispositivi in pausa
È fondamentale fornire un valore di offset accurato. Questo parametro specifica quando è stato creato un media e garantisce che il dispositivo non carichi contenuti che non dovrebbero essere condivisi. Quando un dispositivo è in pausa in Frame.io, l’utente sta indicando che i media creati durante la pausa non devono essere caricati. Per maggiori dettagli, consulta la nostra guida sulla funzionalità di pausa.
Ulteriori vantaggi del parametro offset
Il parametro offset offre un altro vantaggio significativo per organizzare i media all’interno di Frame.io. Quando carichi dei contenuti acquisiti in una data precedente, ad esempio quando un utente seleziona una foto scattata la settimana precedente durante la riproduzione, il parametro offset fa sì che questo contenuto multimediale appaia nelle cartelle corrispondenti alla data di acquisizione originale, invece che alla data di caricamento corrente. Questa organizzazione cronologica mantiene una timeline logica nella struttura dei progetti Frame.io. Senza il parametro offset, i media storici apparirebbero erroneamente raggruppati con i contenuti odierni, creando potenzialmente confusione per gli editor e altri collaboratori. Potresti voler offrire agli utenti una scelta al riguardo nell’interfaccia. Se gli utenti preferiscono organizzare tutti i caricamenti per data corrente, a prescindere da quando è stato acquisito il contenuto multimediale, puoi semplicemente omettere il parametro offset, dato che ha come impostazione predefinita 0 se non è specificato.
La progettazione delle nostre API elimina la necessità che il dispositivo tenga traccia dello stato di pausa. Quando carichi un file, indichi quanti secondi fa è stato creato il file. Il nostro server confronta questo dato con le finestre di pausa e rifiuta il caricamento se è stato creato durante una pausa.
Per dimostrare questa funzionalità, metti in pausa il dispositivo dal menu con i tre puntini nella scheda delle connessioni C2C.
Ora prova a caricare una risorsa:
Specifica dell'endpoint API
La documentazione per /v2/devices/assets è disponibile qui.
Riceverai questo errore:
Se annulli lo stato di pausa del dispositivo e riprovi con la stessa richiesta, la risorsa verrà creata.
Tuttavia, se la risorsa è stata creata durante la finestra di pausa, devi impostare il parametro offset in modo che rifletta quando è stata effettivamente creata la risorsa:
Questo dice a Frame.io che la risorsa è stata creata 60 secondi fa (durante la pausa), attivando correttamente l’errore Channel Paused. È fondamentale che i valori di offset siano accurati per impedire di caricare contenuti sensibili contro la volontà dell’utente, inclusa proprietà intellettuale protetta, filmati sensibili o altro materiale riservato.
Offset e nuovi tentativi
Quando riprovi una chiamata di creazione della risorsa non riuscita, ricorda di aggiornare il valore di offset. Durante periodi prolungati di nuovi tentativi, uno offset statico potrebbe causare uno scostamento al di fuori dalla finestra di pausa, consentendo potenzialmente caricamenti che in realtà dovrebbero essere bloccati.
Caricamento su un canale specifico
Se il dispositivo ha più canali, puoi specificare quale usare:
Se non specificato, il canale predefinito è 0. La maggior parte delle integrazioni non avrà bisogno di modificare questo valore.
Richiesta di un numero di chunk personalizzato
Per impostazione predefinita, il backend di Frame.io divide i file in chunk di circa 25 MB. Per le reti molto congestionate, potrebbe essere utile avere chunk più piccoli. Puoi richiedere un numero specifico di chunk con il parametro parts:
La risposta includerà quattro URL di caricamento:
La dimensione del chunk sarà:
L’ultimo chunk sarà di 5.284.061 byte (calcolato come 21136250 - 5284063 * 3). Quando richiedi numeri di chunk personalizzati, tieni presente le limitazioni per i caricamenti multiparte di AWS S3:
- Ogni parte deve essere di almeno 5 MiB (5.242.880 byte), eccetto l’ultima parte
- Non possono esistere più di 10.000 parti
Se la richiesta viola questi vincoli, riceverai un errore 500: INTERNAL SERVER ERROR:
Verifica sempre che il conteggio personalizzato delle parti sia conforme ai requisiti S3.
Caricamento efficiente
I dispositivi C2C funzionano spesso in ambienti di rete complessi, quindi l’efficienza è fondamentale. Ecco alcune strategie per massimizzare il throughput.
Riutilizzo/pooling delle connessioni TCP
Stabilire connessioni crittografate richiede un sovraccarico significativo in termini di negoziazione. Per un funzionamento efficiente, riutilizza le connessioni TCP se vengono effettuate più richieste. La maggior parte delle librerie HTTP fornisce un’astrazione Client o Session che mantiene connessioni persistenti.
Il processo di negoziazione per una nuova connessione HTTPS include handshake crittografici e convalida dei certificati. Riutilizzando le connessioni, il sovraccarico di verifica una sola volta, anziché per ogni richiesta.
Riferimento per l'handshake TCP
Per dettagli tecnici sui processi di handshake TLS, consulta la spiegazione di Cloudflare.
Per dimostrare il riutilizzo delle connessioni con curl, crea prima una nuova risorsa in Frame.io come descritto nella guida per il caricamento di base.
Quindi, dividi il file in chunk separati per il test:
Ora carica entrambi i chunk su una singola connessione TCP utilizzando il parametro --next di curl:
Confronta il risultato con connessioni separate:
Riutilizzo degli URL dei chunk
Puoi eseguire il caricamento sullo stesso URL di chunk più volte, quindi riutilizza senza problemi gli URL tra i vari esempi.
Nei test, il riutilizzo delle connessioni di solito migliora le prestazioni del 15-20% per i caricamenti sequenziali.
Caricamenti paralleli
Per un throughput ancora maggiore, carica più chunk contemporaneamente:
Se la larghezza di banda è sufficiente, i caricamenti paralleli si completano approssimativamente nel tempo del singolo caricamento più lento.
Per un parallelismo ottimale, una buona regola empirica è due caricamenti simultanei per core della CPU. Il superamento di questo rapporto può portare a conflitti delle risorse e a un rendimento inferiore.
Velocità del caricamento parallelo
Le condizioni di rete influiscono notevolmente sulle prestazioni del caricamento parallelo. In alcuni ambienti, i caricamenti sequenziali possono essere migliori rispetto a quelli paralleli. Le implementazioni avanzate potrebbero monitorare il throughput e regolare dinamicamente la contemporaneità. Esegui sempre la profilazione delle prestazioni nel tuo ambiente di produzione effettivo, invece di fare affidamento sulle tempistiche degli esempi.
Combinazione dei due approcci
Per avere la massima efficienza, combina i pool di connessioni con i caricamenti paralleli. Crea più processi, ognuno dei quali utilizza il pool di connessioni per la propria sequenza di caricamenti:
Funzionalità delle librerie HTTP
La maggior parte delle librerie HTTP fornisce astrazioni per il pool di connessioni e le richieste parallele. Sperimenta con le opzioni della tua libreria per determinare la configurazione ottimale per il tuo ambiente.
Tracciamento dell’avanzamento del caricamento
La tua integrazione deve fornire agli utenti un’indicazione di base dello stato di avanzamento. La granularità a livello di chunk è accettabile: per un caricamento di tre chunk, l’avanzamento potrebbe aumentare da 0% → 33% → 66% → 100% man mano che ogni chunk viene completato.
La generazione di report più dettagliati sull’avanzamento dipende dalle capacità della libreria HTTP che usi. Contatta il nostro team se hai bisogno di aiuto per implementare un tracciamento dell’avanzamento più dettagliato.
Caricamenti affidabili
Per una gestione affidabile degli errori, esamina la nostra guida agli errori. Le sezioni seguenti presuppongono che tu abbia implementato le strategie di gestione degli errori descritte in quella guida.
La creazione di un uploader da usare in produzione richiede considerazioni aggiuntive che vanno oltre la gestione degli errori delle singole richieste.
Creazione di una coda di caricamento
Negli scenari reali, il tuo dispositivo potrebbe generare i media più velocemente di quanto possa caricarli oppure potrebbe subire interruzioni di connessione prolungate. L’implementazione di un sistema di inserimento in coda separa la creazione dei media dalla gestione del caricamento.
Considera un’architettura a due code:
- Una coda dei media per registrare i file locali con Frame.io
- Una coda di chunk per caricare singoli chunk dei file
Ecco un’implementazione semplificata:
Gestione degli errori
Nell’esempio precedente, si assume che le funzioni usate per le chiamate C2C gestiscano gli errori come descritto nella guida agli errori.
Accodamento persistente tra i cicli di potenza
L’approccio con le code in memoria funziona bene quando il dispositivo è acceso, ma cosa succede se l’alimentazione si interrompe prima del completamento dei caricamenti? Per creare un’integrazione davvero resiliente, dobbiamo assicurarci che il dispositivo possa riprendere da dove si era interrotto dopo il riavvio.
Ciò richiede il salvataggio persistente dello stato della coda nell’archiviazione tra i cicli di potenza. Un database integrato come SQLite fornisce una base eccellente per questa funzionalità.
L’implementazione di una coda persistente deve supportare queste operazioni chiave:
- Aggiunta di file appena creati alla coda di caricamento
- Tracciamento della creazione riuscita delle risorse in Frame.io
- Registrazione degli errori di creazione delle risorse
- Archiviazione delle informazioni sui chunk di file per le attività di caricamento
- Recupero del prossimo chunk da caricare
- Contrassegno dei chunk come caricati
- Registrazione degli errori di caricamento dei chunk
- Fornitura di informazioni sullo stato del file per la visualizzazione da parte dell’utente
Ecco come adattare l’esempio precedente per utilizzare un sistema di archiviazione persistente:
Con questo approccio di archiviazione persistente, l’integrazione può affrontare eventuali interruzioni di corrente. Quando il dispositivo si riavvia, continua semplicemente l’elaborazione dall’ultimo stato salvato. Questa architettura fornisce anche le basi per implementare funzionalità più avanzate, come il tracciamento degli errori e il rilevamento dei caricamenti bloccati.
Tracciamento degli errori di caricamento
Un sistema di caricamento affidabile deve tracciare attentamente gli errori. Dopo aver riprovato un’operazione utilizzando le strategie indicate nella guida agli errori, registra questi errori nell’archivio persistente. Ciò consente al sistema di:
- Ridurre la priorità dei caricamenti problematici per impedire che blocchino l’intera coda
- Fornire agli utenti informazioni accurate sullo stato
- Consentire l’intervento amministrativo per problemi persistenti
Quando si verifica un errore irreversibile, contrassegna l’elemento per evitare nuovi tentativi non necessari.
Gestione dei caricamenti bloccati
Implementa delle contromisure per i caricamenti bloccati indefinitamente. Imposta una durata massima (ad es. 30 minuti) dopo la quale un’attività di caricamento di un chunk deve essere terminata e riavviata. Questo previene possibili scenari in cui tutti i worker di caricamento vengono bloccati da operazioni che non rispondono.
Recupero da errori silenziosi
Gli arresti anomali del sistema, la perdita di alimentazione o la terminazione del processo possono impedire la normale generazione di report sugli errori. Quando recuperi elementi dalla coda, registra l’ora di checkout. Se un elemento rimane nello stato “in elaborazione” oltre una soglia ragionevole (ad es. 30 minuti) senza segnalare un’operazione riuscita o non riuscita, rimettilo automaticamente nel pool disponibile per l’elaborazione da parte di un altro worker.
Mitigazione dei caricamenti danneggiati
Un elemento della coda “danneggiato” non riesce mai a causa di problemi intrinseci con i dati o l’ambiente. Se questi elementi continuano a entrare nella coda, possono bloccare l’intero sistema di caricamento. Considera queste strategie per gestire tali casi:
- Dopo più errori, riduci la priorità dell’elemento in modo che il contenuto più recente possa procedere
- Traccia sia gli errori espliciti sia il numero di tentativi di elaborazione
- Segui le best practice di connessione e autorizzazione per distinguere tra problemi ambientali transitori e problemi intrinseci del file
- Implementa limiti di nuovi tentativi progressivi (ad es. riprova le operazioni individuali 10 volte all’interno di ciascuno dei 3 tentativi di lavoro, per un totale di 30 tentativi)
- Fornisci un’interfaccia per ripristinare manualmente i caricamenti problematici una volta risolti i problemi ambientali
I caricamenti danneggiati possono essere causati da:
- Dati di file corrotti che causano errori di I/O
- Errori catastrofici del processo che impediscono la generazione di report sugli errori
- Errori normalmente ripetibili attivati da condizioni sottostanti permanenti
Riprova dopo il riavvio del sistema
Prima di abbandonare definitivamente i caricamenti problematici, contrassegnali per un ultimo tentativo dopo il prossimo riavvio del sistema. Questo risolve i casi in cui i caricamenti non riescono a causa di problemi temporanei dello stato del sistema con memoria, driver o allocazione delle risorse. Se un caricamento continua a non riuscire dopo un riavvio completo, puoi contrassegnarlo con maggiore sicurezza come definitivamente problematico.
Cancellazione della coda
Ricorda di rimuovere i file non disponibili dalla coda. Quando i media vengono rimossi fisicamente o i file vengono eliminati, elimina le voci corrispondenti dalla coda di caricamento per prevenire errori non necessari.
È importante cancellare la coda di caricamento quando ti connetti a un nuovo progetto. I media in coda per un progetto non devono mai apparire in un altro. Quando un utente associa il dispositivo con un progetto diverso, verifica se il progetto è cambiato e, in tal caso, cancella completamente la coda esistente.
Passaggi successivi
Ti incoraggiamo a contattare il nostro team per qualsiasi domanda, poi vai alla guida sui caricamenti avanzati. Saremo lieti di aiutarti nel tuo percorso di implementazione.