0 Replies - 543 Views - Last Post: 02 October 2020 - 04:13 AM Rate Topic: -----

#1 wantsToCode   User is offline

  • D.I.C Head

Reputation: 0
  • View blog
  • Posts: 74
  • Joined: 25-February 19

Apscheduler problem with stopping execution

Posted 02 October 2020 - 04:13 AM

Hi. I've made a Flask-server with what I can manually start and stop a face-detection script. I've also made an endpoint for starting the script with a schedule. For making the schedule I've used the apscheduler-library. It's working fine otherwise, but if I've started the face-detection script with a schedule and I try to stop it before the schedules end_date time, the script keeps looping until the time condition is met. Face detection is stopped so it doesn't try to detect faces after the stop command, but it doesn't stop the function execution. Let me show you my code:

from flask import Flask, request
import os
import datetime
from apscheduler.schedulers.blocking import BlockingScheduler
from apscheduler.schedulers.background import BackgroundScheduler
from main import Detection

app = Flask(__name__)
    
@app.route("/start", methods = ['POST'])
def start():
    end_date = ''
    os.environ['run'] = 'running'
    dt = Detection(end_date)
    dt.detection()

    return 'Detection started'

@app.route("/stop", methods = ['POST'])
def stop():
    os.environ['run'] = 'stop'    

    return 'Detection stopped.'


@app.route("/schedule", methods = ['POST'])
def create():
    os.environ['run'] = 'running'
    start_date = request.form.get('start_date')
    end_date = request.form.get('end_date')
    dt = Detection(end_date)
    sched = BackgroundScheduler()
    sched.add_job(dt.detection, 'cron', start_date=start_date, end_date=end_date)

    sched.start()


    return 'Schedule created.'


if __name__ == "__main__":
    app.run()



And here's my face-detection class:

import cv2
import numpy as np
import imutils
from imutils.video import VideoStream
import os
import time
from datetime import datetime


class Detection:
    def __init__(self, end_date):
        if end_date != '':
            self.end_date = datetime.strptime(end_date, '%Y-%m-%d %H:%M:%S.%f')
        else:
            self.end_date = ''

    def detection(self):
        parent_dir = "/path/to/dir"

        cascPath = "/path/to/dir"

        faceCascade = cv2.CascadeClassifier(cascPath)

        stream = VideoStream(src=0).start()
        time.sleep(2.0)

        currentframe = 0

        while True:
            if end_date != '':
                if self.end_date <= datetime.now() or os.environ.get('run') == 'stop':
                    stream.stream.release()
                    exit()

            else: 
                if os.environ.get('run') == 'stop':
                    stream.stream.release()
                    exit()

            frame = stream.read()

            frame = imutils.resize(frame, width=900)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
            frame = np.dstack([frame, frame, frame])
            frame = cv2.flip(frame, 0)
            faces = faceCascade.detectMultiScale(
                                frame,
                                scaleFactor=1.1,
                                minNeighbors=3,
                        )

            for (x, y, w, h) in faces:
                name = str(currentframe) + '.jpg'
                print('Creating...' + name)
                cv2.imwrite(os.path.join(parent_dir, name), frame)
                currentframe += 1

                if cv2.waitKey(1) & 0xFF == ord('q'):
                    break

        stream.release()



So when I call the start -endpoint the script starts good - and stops when the stop -endpoint is called. But if I start a scheduled detection calling the schedule -endpoint and try to stop it before the end_date condition is fulfilled, it keeps looping this:

while True:
            if end_date != '':
                if self.end_date <= datetime.now() or os.environ.get('run') == 'stop':
                    stream.stream.release()
                    exit()

            else: 
                if os.environ.get('run') == 'stop':
                    stream.stream.release()
                    exit()



It just keeps checking over and over again if that first if (because end_date is not empty when scheduled and then it checks if self.end_date <= datetime.now() or os.environ.get('run') == 'stop':. It finds the env variable "run" which has been set to "stop" when /stop endpoint is called and because of that the script doesn't continue further, it shuts the stream and doesn't look for more faces but it just keeps checking the condition instead of exiting the script. I would highly appreciate any help with how I could make this work in the way I want it to.

This post has been edited by wantsToCode: 02 October 2020 - 04:15 AM


Is This A Good Question/Topic? 0
  • +

Page 1 of 1