Import dữ liệu dùng background job và hiển thị phần trăm tiến trình

Trong bài viết lần này mình sẽ tiếp tục về việc xử lý import hoặc upload một lượng data lớn, yêu cầu thời gian chạy lâu các công nghệ dùng trong bài viết: - ActionCable (websocket) - Background Job - Ajax percent progress bar khi bạn xây dụng một ứng dụng về quản lý hay đơn giản là một trang web quản lý video hoặc các tệp đa phương tiện thì điều chắc hẳn bạn phải suy tính đến đó là "Import data". Khi dữ liệu của bạn quá lớn thì không thể để client cứ phải đợi hết 1 request - respone bình thường được, đương cử là YOUTUBE, khi bạn upload video lên thì sau khi click upload bạn có thể ra xem video khác thoải mái khi upload xong sẽ có một thông báo bật lên là upload success. Trong bài viết này mình sẽ sẻ cách mình tạo ra quá trình import đó. Quy trình và luồng xử lý:

  1. Gửi request submit form dùng Ajax (cái này dễ).
  2. Đưa quá trình import/upload đó vào tiến trình chạy ngầm (dùng background job)
  3. Tính phần trăm imported/uploaded rồi dùng ActionCable (web socket) gửi về và hiện thị trên trang client.

ok trên đó là luồng xử lý, giờ bắt đầu nhé!:nerd: Bước 1: - trước tiên bạn tạo một form import, cái này tùy thẩm mỹ của từng người nhé. trên đây là ví dụng mình tạo một form import 1 file excel. Bước 2: - tiếp theo là phần xử lý gửi thông tin bằng Ajax:

var formData = new FormData(this);
    var url = $(this).attr('action');
    var icon_loading = $(this).find('.loading-import');
    icon_loading.fadeIn(500);
    body_processing();

    $.ajax({
      url: url,
      type: 'POST',
      data: formData,
      cache: false,
      contentType: false,
      processData: false,
      success: function (data) {
        disable_body_processing();//hiển thị icon loading
        $('.browse').attr('disabled', true);
        $('.btn-submit').attr('disabled', true);
        icon_loading.fadeIn(500);
      },
      error: function(){
        disable_body_processing();//tắt icon loading
      },
    });

Bước 3: - xử lý bất đồng bộ, tạo luồng xử lý mới cho việc import dữ liệu trong controller

      file = params[:import_device][:file]
      import_device_object = ImportDevice.new file, current_user.id
      Thread.new {import_device_object.import_device}

Các bạn có thể dùng các gem hỗ trợ về background job như Sidekiq,... nhưng trong bài viết này mình sẽ không đề cập tới nó, bản có thể tìm hiểu thêm ở trên google nhé. Mình sẽ dùng 1 class mà Ruby hỗ trợ cho việc chạy ngầm là Thread.new . Bước 4: - sau khi xử lý tiến trình ở dạng bất đồng bộ rồi giờ tới lúc tính toán chút nhỉ, bạn sẽ chia phần công việc của bạn thành % trả về (tự tạo cách chia cho riêng mình nhé).

      check_percent = (imported.to_f / total)*100.round
      if check_percent <= 100
        ActionCable.server.broadcast "progessbar", imported: check_percent,
          type: "device", filename: @filename
        @check_percent_round += 1
      end

đoạn code trên là sau khi tính được phần trăm imported sẽ gửi dữ liệu về cho client bằng ActionCable (WebSocket). Bước 5: - hiện thị % trên progress bar nào💪:

          var percent = data['imported'].toFixed(2);
          var object_import = $('.form-import-' + data['type']);
          $('.browse').attr('disabled', true);//disable các phím submit trên form
          $('.btn-submit').attr('disabled', true);//disable các phím submit trên form

          object_import.find('.progress-action').css('width', percent + '%');//show phần trăm
          object_import.find('.show-percent').html(percent + '%');
          object_import.find('.show-file-name').val(data['filename']);
          if (percent == 100) {
            object_import.find('.show-percent').html(percent + '%');
            $('.browse').removeAttr('disabled');
            $('.btn-submit').removeAttr('disabled');
            icon_loading.hide();
          }

Ok trên đây là bài viết chia sẻ chút về import dữ liệu dùng background job của mình, cảm ơn mọi người đã đọc nhé, mong là nó có bổ ích cho mọi người 😋😋😋


All Rights Reserved