Flask индикатор выполнения: отображение обработки, но избегание трафика базы данных c и heuristi c time.sleep - PullRequest
0 голосов
/ 04 февраля 2020

Мне нужен индикатор выполнения для обработки данных в Flask проекте . В дополнение к примерам кода я не могу просто сосчитать в al oop, но должен отобразить ход обработки, выполняемой по отдельному маршруту , то есть процент уже обработанных изображений для загрузка и обработка нескольких изображений. Я использую подход, при котором процесс обработки записывает количество изображений для обработки в качестве атрибута пользователя в базу данных (current_user.multipleupload = len (pics)) * , и штрих-код прогресса проверяет изначально сколько уже обработанных картинок существует для текущего пользователя новые записи для этого пользователя были созданы с начала индикатора выполнения (itemcount-iteminital)

В прототипе подход работает. Но я вижу следующие проблемы:

  1. Это приводит к большому количеству обращений к базе данных, проверяя по истечении time.sleep (2) непрерывно количество обработанных изображений для текущего пользователь.

  2. Мне пришлось использовать начальный time.sleep (0,5) при инициализации прогресса l oop, потому что в противном случае процесс отображения прогресса уже начался до того, как обработка изображения запустил и положил количество снимков, которые нужно обработать, в базу данных. Значение 0.5 было найдено, играя, и я не ожидаю, что это будет работать в производственном процессе с другой инфраструктурой и одновременным доступом.

Какой лучший способ получить информацию от обработка l oop до индикатора выполнения l oop? Я пытался использовать сеанс вместо базы данных, что это не сработало вообще.

Progress l oop:

@items.route('/progress')
def progress():

    @stream_with_context
    def import_progress():
        time.sleep(0.5)
        with current_app.app_context():
            iteminital = Item.query.filter_by(owner=current_user).count() - 1
            if current_user.multipleupload:
                    itemstargetcount = current_user.multipleupload
        continueloop = True
        while continueloop:            

            with current_app.app_context():
                itemcount = Item.query.filter_by(owner=current_user).count()                

            percentage = round(100 * (itemcount-iteminital) / itemstargetcount) 

            sse_id = str(percentage)
            sse_data = str(percentage)
            sse_event = 'import-progress'

            if percentage == 100:
                sse_event = 'last-item'
                sse_data = '/home'

            yield "id:{_id}\nevent:{event}\ndata:{data}\n\n".format(
                _id=sse_id, event=sse_event, data=sse_data)
            time.sleep(2)

    return Response(import_progress(), mimetype='text/event-stream')

Обработка:

@items.route("/items/new", methods=['GET', 'POST'])
@login_required
def new_multipleitem():
    form = MultipleItemForm()

    if form.validate_on_submit():  
        pics = request.files.getlist(form.item_files.name)
        if pics:            
           current_user.multipleupload = len(pics)
           db.session.commit()
           founderror=False
           for pic in pics:
               filename = pic.filename
               try:

       ..... (PROGRESSING OF THE PICTURE INCLUDING CREATION OF A DATA BASE ENTRY)

    return render_template('multiple_item.html', title='New Items', form=form, legend=gettext('New Items'), itemsall=itemsall, searchform=searchform)

Для завершения сценарий, кнопка и индикатор выполнения в html:

<script> 
function getProgress() {

        var source = new EventSource("/progress"); 

        source.addEventListener('import-progress', function(event)
            {
                $('.progress-bar')
                    .css('width', event.data + '%')
                    .attr('aria-valuenow', event.data);
                $('.progress-bar-label').text(event.data + '%');    
            }, false
        );

        source.addEventListener("/home", function(event)
           {
             source.close();
             redirect(event.data);
           }, false
        );
}    

function redirect(url) {
  document.location = url;
}

...

<div class="form-group">
        {{ form.submit(class="btn btn-outline-info", onclick="getProgress()") }}
    </div>

.....

<div class="progress" style="width: 80%; margin: 50px;">
    <div class="progress-bar progress-bar-striped active"
      role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%">
      <span class="progress-bar-label">0%</span>
    </div>
  </div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...