ronon's avatar
Level 9

Share image on multiple sites after image job is processed

A user can upload any amount of images to a server. There the image is stored in the database and processed afterwards.

The user can select mutliple services before the upload, which tells the script, where he wants to share the image. FB, Twitter, etc...

First step I store the image in the database:

Image::create([values]);

Next I convert and resize the image with a job and chain it with the ShareImage job

ProcessImage::dispatch($image);

But now that the user can select only the sites where he wants to share the image, i don't know how to create a job for each site the image should be shared on.

Should I chain the jobs and the last job creates new jobs for each site?

ProcessImage::dispatch($image);->chain([
    new ShareImage($image)
]);

ShareImage

class ShareImageimplements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;


    protected $image;
    protected $sites;

    /**
     * Create a new job instance.
     *
     * @return void
     */
    public function __construct(Image $image, $sites = [])
    {
        $this->image= $image;
    $this->sites = $sites;
    }

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        foreach($this->sites as $site){
        // Determine the site with a Factory
              // Now generate a job for it, or....? 
    }
    }
}

Would this be a good approach or...?

I thought about creating the chain array dynamically, but this would make each site dependent from the previous job, right? Or is there a way to create only from the main job dependable jobs?

0 likes
3 replies
AlexDemin's avatar
Level 16

Your logic looks good. Just a couple of edits.

Your controller

// create an image
$image = Image::create([values]);

// dispatch chained jobs
ProcessImage::withChain([
    new ShareImage($image, $request->sites);
])->dispatch($image);

Your ShareImage job

class ShareImage implements ShouldQueue
{

    //..

    /**
     * Execute the job.
     *
     * @return void
     */
    public function handle()
    {
        foreach($this->sites as $site){

            // you can process all sites with one single job
            // and share $this->image on the $site right here

            // another way is to dispatch a new job for each site
            // ShareImageOnSite::dispatch($this->image, $site);

        }
    }

}
1 like
ronon's avatar
Level 9

I would like that the sites are processed kinda parallel. So I think creating a new job for each site would be the better way?!?

AlexDemin's avatar

I would like that the sites are processed kinda parallel. So I think creating a new job for each site would be the better way?!?

Yes. I'd say the only way.

Please or to participate in this conversation.