ResilientMediaStorageService.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. <?php
  2. namespace App\Services;
  3. use Storage;
  4. use Illuminate\Http\File;
  5. use Exception;
  6. use GuzzleHttp\Exception\ClientException;
  7. use Aws\S3\Exception\S3Exception;
  8. use GuzzleHttp\Exception\ConnectException;
  9. use League\Flysystem\UnableToWriteFile;
  10. class ResilientMediaStorageService
  11. {
  12. static $attempts = 0;
  13. public static function store($storagePath, $path, $name)
  14. {
  15. return (bool) config_cache('pixelfed.cloud_storage') && (bool) config('media.storage.remote.resilient_mode') ?
  16. self::handleResilientStore($storagePath, $path, $name) :
  17. self::handleStore($storagePath, $path, $name);
  18. }
  19. public static function handleStore($storagePath, $path, $name)
  20. {
  21. return retry(3, function() use($storagePath, $path, $name) {
  22. $baseDisk = (bool) config_cache('pixelfed.cloud_storage') ? config('filesystems.cloud') : 'local';
  23. $disk = Storage::disk($baseDisk);
  24. $file = $disk->putFileAs($storagePath, new File($path), $name, 'public');
  25. return $disk->url($file);
  26. }, random_int(100, 500));
  27. }
  28. public static function handleResilientStore($storagePath, $path, $name)
  29. {
  30. $attempts = 0;
  31. return retry(4, function() use($storagePath, $path, $name, $attempts) {
  32. self::$attempts++;
  33. usleep(100000);
  34. $baseDisk = self::$attempts > 1 ? self::getAltDriver() : config('filesystems.cloud');
  35. try {
  36. $disk = Storage::disk($baseDisk);
  37. $file = $disk->putFileAs($storagePath, new File($path), $name, 'public');
  38. } catch (S3Exception | ClientException | ConnectException | UnableToWriteFile | Exception $e) {}
  39. return $disk->url($file);
  40. }, function (int $attempt, Exception $exception) {
  41. return $attempt * 200;
  42. });
  43. }
  44. public static function getAltDriver()
  45. {
  46. $drivers = [];
  47. if(config('filesystems.disks.alt-primary.enabled')) {
  48. $drivers[] = 'alt-primary';
  49. }
  50. if(config('filesystems.disks.alt-secondary.enabled')) {
  51. $drivers[] = 'alt-secondary';
  52. }
  53. if(empty($drivers)) {
  54. return false;
  55. }
  56. $key = array_rand($drivers, 1);
  57. return $drivers[$key];
  58. }
  59. }