2021년 12월 12일 일요일

python flask 응답이 느릴때 처리, processing중임을 표시하기


앞에서 간단한 계산기를 Flask로 구현해보았습니다. 계산기는 간단한 예일 뿐이고 실제는 좀더 복잡한 처리를 하게될겁니다. 

만약 복잡한 처리에 시간이 오래 걸린다면 어떻게 될까요?

계산기에 sleep 코드를 넣고 시험을 해보았습니다.


기존 코드

def calc(inputdata):

return str(eval(inputdata))


작업된 코드 10초 기다림

def calc(inputdata):

print("calc")

time.sleep(10)

return str(eval(inputdata))


예상은 브라우저가 계속 로딩중이 뜰줄 알았는데, 실제는 그렇지 않습니다.


위 화면이 10초 머무르다가

10초 후에 결과가 나오는 형태가 됩니다.


좀더 자연스러운 결과가 나오도록 수정해보겠습니다.

submit 버튼을 누르면 화면에 처리중이라는 표시가 나오도록 만들고 처리가 끝나면 결과가 나오도록 하면 됩니다.


기존 코드

<script>

$( "#btn1" ).click(function() {

var txt1_v = $('#txt1').val();

var postdata = {

'inputdata':txt1_v

}

<!--alert( "Handler for .click() called." );-->

$.ajax({

type: 'POST',

url: '{{url_for("ajax_page")}}',

data: JSON.stringify(postdata),

dataType : 'JSON',

contentType: "application/json",

success: function(data){

$("#result1").text("result:"+data['inputdata'] + '=' + data['rlt']);

<!--alert('success :' + data['inputdata'] + '=' + data['rlt'])-->

},

error: function(request, status, error){

alert('ajax error:['+status+']['+error+']')

}

})

});


</script>


변경 코드

<script>

$( "#btn1" ).click(function() {

var txt1_v = $('#txt1').val();

var postdata = {

'inputdata':txt1_v

}

$("#result1").text("processing...")

<!--alert( "Handler for .click() called." );-->

$.ajax({

type: 'POST',

url: '{{url_for("ajax_page")}}',

data: JSON.stringify(postdata),

dataType : 'JSON',

contentType: "application/json",

success: function(data){

$("#result1").text("result:"+data['inputdata'] + '=' + data['rlt']);

<!--alert('success :' + data['inputdata'] + '=' + data['rlt'])-->

},

error: function(request, status, error){

alert('ajax error:['+status+']['+error+']')

}

})

});


</script>


submit 버튼을 누르면 아래와 같은 화면이 표시되고 여기에서 10초 간 머무르게 됩니다.



그리고 결과는 기존처럼 나옵니다.


전체 코드

flask 코드

import time
from flask import Flask
from flask import request
from flask import render_template
from flask import jsonify

app = Flask(__name__)

@app.route("/")
def index():
	return render_template('input_form_loading.html')

@app.route("/ajax_page", methods=['POST'])
def ajax_page():
	data = request.get_json()
	print(data)
	calc_result = calc(data['inputdata'])
	rdata = {}
	rdata['inputdata']=data['inputdata']
	rdata['rlt']=calc_result
	print(rdata)
	return jsonify(rdata)

def calc(inputdata):
	print("calc")
	time.sleep(10)
	return str(eval(inputdata))

if __name__ == "__main__":
	app.run(port=8080, debug=True)


html 코드 templates/input_form_loading.html

<!--https://api.jquery.com/click/-->
<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <title>calc flask demo</title>
  <script src="https://code.jquery.com/jquery-3.5.0.js"></script>
</head>
<body>
 
<input type="text" id="txt1" name="inputdata"></input>
<button id="btn1">submit</button>

<div id="result1">
</div>

</p>

<script>
$( "#btn1" ).click(function() {
	var txt1_v = $('#txt1').val();
	var postdata = {
		'inputdata':txt1_v
	}
	$("#result1").text("processing...")
	<!--alert( "Handler for .click() called." );-->
	$.ajax({
		type: 'POST',
		url: '{{url_for("ajax_page")}}',
		data: JSON.stringify(postdata),
		dataType : 'JSON',
		contentType: "application/json",
		success: function(data){
			$("#result1").text("result:"+data['inputdata'] + '=' + data['rlt']);
			<!--alert('success :' + data['inputdata'] + '=' + data['rlt'])-->
		},
		error: function(request, status, error){
			alert('ajax error:['+status+']['+error+']')
		}
	})
});

</script>
 
</body>
</html>


전반적으로 필요한 내용들은 모두 한것 같습니다.

당연한거지만 한가지 더 실험을 해보겠습니다. 여러명이 동시에 브라우저 접속이 일어난다면 어떻게 될까요?

당연한것이지만 flask가 thread를 여러개 생성시켜서 잘 처리해줍니다. 이 부분을 고려해서 여러프로세서 동기화 처리 작업을 하면 됩니다.




댓글 없음:

댓글 쓰기