0

I am running multiple servers and have an issue when people Publish a post immediately after uploading a Featured image, the image is is not available on all server immediately.

I know that I can have everyone schedule posts BUT I would ideally like to simply insert a delay when the click on Publish of several minutes. Any ideas on how this might be accomplished would be super helpful.

4
  • Can you tell us more about your servers setup? Are you using a distributed filesystem? How are you mirroring your files to other servers?
    – kovshenin
    Commented Jul 29, 2015 at 17:12
  • I'm using Lsyncd to simply mirror servers behind a load balancer. I have wp-admin that connects to the master. Files are mirrored very quickly but we have 1M+ visitors a day which means that right after hitting the publish button, a certain amount of traffic is hitting a server other than the master. A couple of minutes delay is all I need to ensure that no one sees a missing image.
    – Joe Conlin
    Commented Jul 29, 2015 at 17:34
  • Perhaps you can make some sort of custom tailored solution using wp_insert_post_data and introduce some sort of delay. Of course that could lead to unexpected behavior with some server configs. My two cents: Even if you schedule the post for let's say 5 minutes later, you'll need to use the wp cron. Since wp cron is used with scheduled post why not just "edit" a bit the functionality of the publish button and make it do the same thing as the "Schedule a post" button? It will just add a fixed date instead of making the user to choose a date. Commented Jul 29, 2015 at 18:31
  • I've just got an Idea. But it's again related with scheduled posts. using wp_insert_post_data you can manipulate the post's data prior to inserting it to the database (post_date). That way you can increment the publish date and it will be in fact a scheduled post. Commented Jul 29, 2015 at 18:38

1 Answer 1

1

I think that by adding a delay you're not really fixing the issue, you're simply hiding it, until you grow and add more media and servers, so lsyncd will take longer, and you'll have to increase your delay every time.

Also what about updating existing posts? People might add media items and update, or add more items to a gallery, you'll have to add delays on every save action, sounds very hacky, fragile and bad UX.

I can think of three approaches to fix the problem. First, you can proxy requests to wp-content/uploads to your "master" server if the requested file was not found on the target server. I think you can do this with try_files in nginx:

try_files $uri @proxy;
location @proxy {
    proxy_pass http://master:80;
}

This should work well with your current setup, and @proxy will kick in when replication with lsyncd hasn't finished yet.

The second approach would be to use a distributed filesystem, such as GlusterFS or Ceph. You can use them in an NFS-like fashion, i.e. mounted, readable and writable on several nodes at once, so you no longer have to have a "master" web server -- every one of them would be able to write to the filesystem.

Note, however, that doing lots of file IO on a mounted remote filesystem can very easily become a performance bottleneck (#31066 comes to mind) so make sure you have some kind of disk io caching and very low latency (same rack or same datacenter at least) between your web servers and the filesystem cluster.

Third option would be object storage, preferably with HTTP access, like Amazon S3. It'll require more heavy-lifting since now you'll have to move all your uploaded files to a remote destination (don't be fooled by s3fs, it's a can of worms) and you won't be able to easily do things locally, such as regenerate thumbnails, read EXIF data off of a local file, etc.

Now, to answer your original question. Instead of adding a delay I suggest you look into scheduling a post to be published, say 5 minutes from when the users hit the Publish button. For that I'd look into the transition_post_status action, watch for the draft => publish transition and change it to future with wp_insert_post().

Hope that helps!

1
  • Thanks for taking the time to post this answer. Currently, I have everyone scheduling posts a minimum of 5 min out, I just would like to have a more transparent solution. Switching to a distributed file system or even a CDN option isn't really a road I want to go down to solve this one issue. You solution in the last paragraph is the direction I'm heading. I'll post the exact code once I have it working.
    – Joe Conlin
    Commented Jul 29, 2015 at 19:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.