arrrssssss's avatar

Handling Load of External Media to Frontend

Hi community,

In my latest laravel, vue, inertia project, I use an API to retrieve some data from external server, this API in response to each request retrieved 30 records, each record contains photos array every photo has link and unique id,

photos are stored in a server that are not reachable for my application users due to location network restrictions, so I have to transfer those photos to my own server for this purpose, I do these steps

  1. in controller for every API record I iterate over photos and store them in database

  2. transfer the model that store in db to a created job, while the job finished it run a ShouldBroadcast event to send these transferred image to frontend (vue)

  3. in frontend I use reverb and echo to catch this broadcasted event, and show the transferred image to user

but the main problem is, when there is a bunch of events broadcasts to echo, some of them seems to get lost !!

this is the code in front end to handle the received event

Echo.channel(Media.Process.${props.uuid}) .listen('.photo.created', (event) => {

        const processedPhoto = event.media

        const photoToUpdate = localPhotoLookup.get(processedPhoto.uid)
        if (photoToUpdate && processedPhoto.processed) {
            const targetPhoto = localData.value
                .flatMap(obj => obj.photos)
                .find(photo => photo.uid === processedPhoto.uid)

            if (targetPhoto) {
                Object.assign(targetPhoto, processedPhoto)
            }
        }
    })

for each data loaded via axios from backend, I store its photos to a Map in javascript with key of photo UID and value of photo object, so can find processed photo in an easy way and while I update target photo with reactivity of vue it shown to users.

but right now what can I do for some photos that are broadcasts from backend, received with echo but these code block seems skipped due to high count of events ?

Regards

0 likes
1 reply
LaryAI's avatar
Level 58

To address the issue of some broadcasted events being lost or skipped when handling a high volume of events in your Laravel, Vue, and Inertia application, you can consider the following strategies:

  1. Debouncing or Throttling Events: Implement debouncing or throttling on the frontend to manage the rate at which events are processed. This can help prevent overwhelming the client-side with too many events at once.

    import _ from 'lodash';
    
    const handlePhotoCreated = _.debounce((event) => {
        const processedPhoto = event.media;
    
        const photoToUpdate = localPhotoLookup.get(processedPhoto.uid);
        if (photoToUpdate && processedPhoto.processed) {
            const targetPhoto = localData.value
                .flatMap(obj => obj.photos)
                .find(photo => photo.uid === processedPhoto.uid);
    
            if (targetPhoto) {
                Object.assign(targetPhoto, processedPhoto);
            }
        }
    }, 100); // Adjust the debounce delay as needed
    
    Echo.channel(`Media.Process.${props.uuid}`)
        .listen('.photo.created', handlePhotoCreated);
    
  2. Batch Processing: Instead of broadcasting each photo individually, consider batching multiple photos into a single event. This reduces the number of events and can help ensure that all photos are processed.

    // In your Laravel job or event
    event(new PhotosCreated($photosBatch));
    
    // On the frontend
    Echo.channel(`Media.Process.${props.uuid}`)
        .listen('.photos.created', (event) => {
            event.photos.forEach(processedPhoto => {
                const photoToUpdate = localPhotoLookup.get(processedPhoto.uid);
                if (photoToUpdate && processedPhoto.processed) {
                    const targetPhoto = localData.value
                        .flatMap(obj => obj.photos)
                        .find(photo => photo.uid === processedPhoto.uid);
    
                    if (targetPhoto) {
                        Object.assign(targetPhoto, processedPhoto);
                    }
                }
            });
        });
    
  3. Ensure Reliable Event Delivery:

    • Retry Logic: Implement retry logic on the server-side to ensure that events are re-sent if they fail to be delivered.
    • Queue Configuration: Ensure that your queue workers are properly configured to handle the load. You might need to increase the number of workers or adjust the queue settings.
  4. Logging and Monitoring: Implement logging on both the server and client sides to monitor event delivery and processing. This can help identify where events are being lost.

  5. WebSocket Connection Stability: Ensure that your WebSocket connection is stable. Check for any network issues or limitations that might be causing disconnections.

By implementing these strategies, you should be able to handle a high volume of events more reliably and ensure that all photos are processed and displayed to the user.

Please or to participate in this conversation.