0

私はこれを機能させていますが、1ダースほどのファイルでも非常に遅いです(タイムアウトになるまで)。

ドロップボックスからディレクトリリストを取得し、それをテーブルの内容と比較します。これを最適化して、可能な限り高速かつ効率的に実行できるようにしたいと思います。毎回クエリを実行するのが最適ではないことはわかっていPhoto.createますが、ドロップボックスフォルダーからAmazon S3に(を介してcarrierwave gem)ファイルをコピーするため、メソッド中に大きな遅延が発生すると思います。遅延がどこから来ているのかを確認するために、操作に時間をかけることを検討しています。10個のファイルがあるフォルダの場合、ページの読み込みに1分以上かかります。奇妙なことに、それらのファイルはすでに存在しているためにスキップしても、これほど時間がかかるので、私には意味がありません。

これが私のコントローラーコードです:

def sync
    photo_size = 1024
    @event = Event.find(params[:id])

    @client = Dropbox::API::Client.new(:token  => 'derp', :secret => 'herp')
    @dropbox_files = @client.ls "images/#{@event.keyword}/#{photo_size}/"

    @existing_photos = @event.photos.all
    @data = []

    # TODO: need to make it not add files multiple times


    @dropbox_files.each do |f|


      photo_exists = Photo.where(:dropbox_path => f.direct_url.url).count
      if photo_exists == 0
        @photo = Photo.create(:remote_filename_url => f.direct_url.url, 
                              :dropbox_path => f.direct_url.url,
                              :event_id => @event.id)
        @data << "Added: #{f.direct_url.url.split('/').last}"
      else
        @data << "Skipped: #{f.direct_url.url.split('/').last}"
      end
    end
  end

理想的には、各呼び出しを非同期リクエストに分割したいのですPhoto.createが、それはまったくのことではないかもしれません。今のところ、100枚のリストから5枚の写真をタイムアウトせずに追加できるものであれば嬉しいです。

これを行うための最良の方法は何ですか?私はRoR3を初めて使用するPHPプログラマーです。助けてください。ありがとう!

注:今のところ、これは画面に出力されますが、最終的にはバックグラウンドアクションになります。

4

2 に答える 2

1

私はあなたが試すことができるいくつかのことを持っています。私はDropboxAPIに精通していませんが、これを理解できるはずです。

最後の同期の日付を保存し、新しいファイルまたは変更されたファイルのみを取得します。

メソッドを新しいクラスに抽出します。syncコントローラーは、この責任にとっておそらく最良の選択ではありません。これを行う方法の例を次に示します。

class EventSync
  attr_reader :event

  def initialize(event_or_id)
    @event = Event.find(event_or_id)
  end

  def sync
    dropbox_files.each do |f|
      process_file(f)
    end
  end

  private
    def photo_size
      1024
    end

    def process_file(file)
      event.photos.where(dropbox_path: file.direct_url.url).first_or_create do |file|
        file.remote_filename_url = file.direct_url.url
      end 
    end

    def client
      @client ||= Dropbox::API::Client.new(:token  => 'derp', :secret => 'herp')
    end

    def dropbox_files
      @dropbox_files ||= client.ls "images/#{event.keyword}/#{photo_size}/"
    end

end

これは次のように使用されますEventSync.new(params[:event_id]).sync

これを多くの小さなメソッドに分割することで、ベンチマークが容易になり(各メソッドを個別にテストできます)、速度低下がどこにあるかをより適切に特定できるようになります。

于 2012-11-24T21:40:39.177 に答える
0

これは、ザックの方法を試す前に、私が今それを機能させる方法です。

コントローラの場合:

  def syncall
    #TODO: Refactor sync and syncall
    photo_size = 1024
    @event = Event.find(params[:id])

    new_image_dir = "images/#{@event.keyword}/#{photo_size}/"
    @client = Dropbox::API::Client.new(:token  => 'uuzpqar2m5839eo', :secret => 'nr9tmx0vc8qh892')
    @dropbox_files = @client.ls new_image_dir
    start = Time.now  

    existing_photos = @event.photos.all
    @data = []
    photo_list = []

    existing_photos.each do |ep|
      filename = URI.unescape(ep.dropbox_path.split('/').last) #dropbox_path is url encoded...
      photo_list << filename
    end
    @data << photo_list

    skipped_files = 0

    @dropbox_files.each do |f|
      sql_start = Time.now
      db_filename = f.path.split('/').last

      if photo_list.include? db_filename 
        skipped_files += 1
      else
        pc_start = Time.now
        if db_filename.split('.').last == 'jpg'
          db_path = f.direct_url.url
          @photo = Photo.create(:remote_filename_url => db_path, 
                                :dropbox_path => db_path,
                                :event_id => @event.id)
          @data << "#{db_filename} added in #{Time.now - pc_start} seconds"
        else
          @data << "#{db_filename} was skipped in #{Time.now - pc_start} seconds"
        end
      end
    end    
    @data << "Total Time: #{Time.now - start} (#{skipped_files} skipped.)"
  end

このように、追加するファイルがない場合、実行されるクエリは1つだけです。もう1つの問題は、direct_url.url呼び出されるたびにドロップボックスに接続するため、呼び出しがかなり重いことです。

スキップされた写真ごとに約2秒から.01秒になり、アップロードされた写真ごとに5-7秒から2-4秒になりました。私はまだザックの方法が好きなので、今から試してみます。

于 2012-11-27T20:26:04.473 に答える