diff --git a/app/Services/OpenId/UserService.php b/app/Services/OpenId/UserService.php index 5522bb9c..9c7efd00 100644 --- a/app/Services/OpenId/UserService.php +++ b/app/Services/OpenId/UserService.php @@ -378,8 +378,12 @@ public function updateProfilePhoto($user_id, UploadedFile $file, $max_file_size $path = User::getProfilePicFolder(); Log::debug(sprintf("UserService::updateProfilePhoto user %s saving file to swift path %s fileName %s", $user_id, $path, $fileName)); - Storage::disk(Config::get("filesystems.cloud"))->putFileAs($path, $file, $fileName, 'public'); + $storage = Storage::disk(Config::get("filesystems.cloud")); + if (is_null($storage)) { + throw new \Exception("can't save profile picture in the remote storage."); + } + $storage->putFileAs($path, $file, $fileName, 'public'); $user->setPic($fileName); return $user; diff --git a/app/libs/Utils/FileSystem/SwiftServiceProvider.php b/app/libs/Utils/FileSystem/SwiftServiceProvider.php index 7152d368..5760c3cf 100644 --- a/app/libs/Utils/FileSystem/SwiftServiceProvider.php +++ b/app/libs/Utils/FileSystem/SwiftServiceProvider.php @@ -11,18 +11,51 @@ * See the License for the specific language governing permissions and * limitations under the License. **/ + use App\Services\FileSystem\Swift\SwiftAdapter; +use Carbon\Carbon; +use Illuminate\Support\Facades\Cache; use Illuminate\Support\Facades\Log; use Illuminate\Support\Facades\Storage; -use League\Flysystem\Filesystem; use Illuminate\Support\ServiceProvider; +use League\Flysystem\Filesystem; use OpenStack\OpenStack; + /** * Class SwiftServiceProvider * @package App\Services\FileSystem\Swift */ final class SwiftServiceProvider extends ServiceProvider { + const MAX_SKIPS = 4; + + private function shouldBypass(): bool + { + $skip_until = Cache::tags(SwiftServiceProvider::class)->get('skip_until', Carbon::now()); + return Carbon::now() < $skip_until; + } + + private function recalculateSkipDelay() + { + $cache = Cache::tags(SwiftServiceProvider::class); + $skip_count = intval($cache->get('skip_count', 0)); + $skip_delay = intval($cache->get('skip_delay', 1)); + $skip_count++; + $skip_delay = $skip_delay * pow(2, $skip_count - 1); + $skip_until = Carbon::now()->add($skip_delay, 'minutes'); + $cache->put('skip_count', $skip_count); + $cache->put('skip_delay', $skip_delay); + $cache->put('skip_until', $skip_until); + if ($skip_count > self::MAX_SKIPS) { + $this->resetSkips(); + } + } + + private function resetSkips() + { + Cache::tags(SwiftServiceProvider::class)->flush(); + } + /** * Register bindings in the container. * @@ -43,6 +76,9 @@ public function boot() Storage::extend('swift', function ($app, $config) { try { + if (empty($config["auth_url"]) || empty($config["region"]) || empty($config["container"])) return null; + + if ($this->shouldBypass()) return null; $configOptions = [ 'authUrl' => $config["auth_url"], @@ -82,10 +118,13 @@ public function boot() $container = $openstackClient->objectStoreV1()->getContainer($config["container"]); + $this->resetSkips(); + return new Filesystem(new SwiftAdapter($container)); } catch (\Exception $ex){ Log::error($ex); + $this->recalculateSkipDelay(); return null; } });