浏览代码

抠图阻塞问题

rambo 5 月之前
父节点
当前提交
1dce732ec0

+ 4 - 4
python/api.py

@@ -23,12 +23,11 @@ import importlib
 from service.auto_deal_pics.upload_pic import UploadPic
 from service.OnePicTest import OnePicTest
 from service.base import check_move_goods_art_no_folder
-import hashlib
 import win32api, win32gui, win32con
 from win32gui import EnumWindows, GetWindowText
 from service.online_request.module_online_data import OnlineDataRequest
-
-
+from concurrent.futures import ThreadPoolExecutor
+from functools import partial
 
 @app.get("/")
 async def index():
@@ -193,6 +192,7 @@ async def fromExcelHandler(params: HandlerDetail):
         temp_class_dict[key] = cls
 
     config_data["temp_class"] = temp_class_dict
+    executor = ThreadPoolExecutor(max_workers=4)
     # 此处对抠图进行批量处理,保证所有的图片在生成详情图之前已经完成抠图,以保证详情图生成的效率
     return_data = run_main.check_before_cutout(config_data)
     cutout_res = run_main.check_for_cutout_image_first_call_back(return_data)
@@ -396,7 +396,7 @@ async def handle_detail(request: Request, params: HandlerDetail):
 
     config_data["temp_class"] = temp_class_dict
     return_data = run_main.check_before_cutout(config_data)
-    cutout_res = await run_main.check_for_cutout_image_first_call_back(return_data)
+    cutout_res = run_main.check_for_cutout_image_first_call_back(return_data)
     check_for_detail_first_res = None
     if cutout_res == True:
         sys_path = format(os.getcwd()).replace("\\", "/")

+ 11 - 10
python/service/base_deal.py

@@ -3,7 +3,7 @@ from .module_generate_goods_art_no_table import GenerateGoodsArtNoTable
 from func_timeout import FunctionTimedOut
 from .grenerate_main_image_test import GeneratePic
 from threading import Lock
-
+from middleware import UnicornException
 import settings
 from collections import defaultdict
 from .remove_bg_ali import RemoveBgALi, Picture
@@ -40,14 +40,15 @@ class BaseDealImage(object):
         self.image_dir = image_dir
         pass
 
-    async def run_main(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=None,
+    def run_main(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=None,
                  resize_image_view=None, windows=None, logo_path=None, image_order_list=None):
         # 对所有缺失已抠图的进行抠图处理
-        await self.run_cutout_image(all_goods_art_no_folder_data=all_goods_art_no_folder_data,
-                              callback_func=callback_func,
-                              cutout_mode=cutout_mode,
-                              windows=windows,
-                              )
+        self.run_cutout_image(
+                all_goods_art_no_folder_data=all_goods_art_no_folder_data,
+                callback_func=callback_func,
+                cutout_mode=cutout_mode,
+                windows=windows,
+            )
         error_num = 0
         successful_num = 0
         for goods_art_no_folder_data in all_goods_art_no_folder_data:
@@ -407,7 +408,7 @@ class BaseDealImage(object):
             path = "{}/{}".format(root_path, i)
             self.check_path(path)
 
-    async def run_cutout_image(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=1, windows=None):
+    def run_cutout_image(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=1, windows=None):
         """
         处理所有的抠图
         """
@@ -467,9 +468,9 @@ class BaseDealImage(object):
             if cutout_mode == '2':
                 dealCutout = DealCutout(windows=None, token=self.token)
                 dealCutout.need_cutout_images = cutImageList
-                await dealCutout.run()
+                dealCutout.run()
                 while True:
-                    await asyncio.sleep(1)
+                    time.sleep(0.5)
                     # if windows:
                     #     if windows.state != 1:
                     #         break

+ 3 - 5
python/service/deal_cutout.py

@@ -60,11 +60,9 @@ class DealCutout():
             #                 "message": "精细化抠图余量不足",
             #                 })
             raise UnicornException("精细化抠图余量不足")
-            return False
-
         return True
 
-    async def run(self):
+    def run(self):
         """
         need_cutout_images 结构:
         [
@@ -104,7 +102,7 @@ class DealCutout():
                 num=num,
                 token=self.token,
             )
-            res2 = await deal2.run()
+            res2 = deal2.run()
             try:
                 image_path = res2
                 if image_path:
@@ -120,7 +118,7 @@ class DealCutout():
                 num=num,
                 token=self.token,
             )
-            res1 = await deal1.run()
+            res1 = deal1.run()
             # tasks_1.append(task_1)
             print("res1===>", res1)
             try:

+ 7 - 7
python/service/deal_one_image.py

@@ -111,9 +111,9 @@ class DealOneImage(Base):
         self.file_name = image_data["file_name"]
         self.out_path = image_data["out_path"]
 
-    async def run(self):
+    def run(self):
         # 直接调用抠图
-        await asyncio.sleep(0.1)
+        time.sleep(0.01)
         # 1、增加获取key,2、key需要加密、3、429报错 重试再来拿一个KEY
         self.add_log("开始处理")
         self.send_info(text="{} 处理中".format(self.file_name))
@@ -131,7 +131,7 @@ class DealOneImage(Base):
             if self.file_path in self.windows.upload_pic_dict:
                 break
             else:
-                await asyncio.sleep(1)
+                time.sleep(1)
                 if n <= 0:
                     self.send_info(text="{} 处理超时", is_success=False)
                     return
@@ -230,7 +230,7 @@ class DealOneImage(Base):
                         pixian_cutout_data["status_code"]
                     )
                 )
-                await asyncio.sleep(6)
+                time.sleep(6)
                 continue
 
             elif pixian_cutout_data["status_code"] == 429:
@@ -250,7 +250,7 @@ class DealOneImage(Base):
                         self.file_name, pixian_cutout_data["status_code"]
                     )
                 )
-                await asyncio.sleep(10)
+                time.sleep(10)
                 continue
             else:
                 self.send_info(
@@ -359,7 +359,7 @@ class DealOneImageBeforehand(Base):
         self.r_ali = RemoveBgALi()
         self.file_name = image_data["file_name"]
 
-    async def run(self):
+    def run(self):
         while 1:
             if self.windows.state != 1:
                 return
@@ -372,7 +372,7 @@ class DealOneImageBeforehand(Base):
             if f:
                 break
             else:
-                await asyncio.sleep(1)
+                time.sleep(1)
                 continue
         image_deal_info = {}
         try:

+ 107 - 39
python/service/run_main.py

@@ -185,7 +185,7 @@ class RunMain:
         return return_data
 
     # 抠图校验后的回调函数处理
-    async def check_for_cutout_image_first_call_back(self, return_data):
+    def check_for_cutout_image_first_call_back(self, return_data):
         # return_data = {
         #     "code": 99,
         #     "message": "",
@@ -270,15 +270,28 @@ class RunMain:
             goods_art_no_folder_data["folder_name"]
             for goods_art_no_folder_data in all_goods_art_no_folder_data
         ]
-        await sendSocketMessage(
-            code=0,
-            msg="开始处理抠图",
-            data={
-                "status": "进行中",
-                "goods_art_nos": goods_arts,
-            },
-            msg_type="segment_progress",
-        )
+        try:
+            loop = asyncio.get_event_loop()
+            loop.create_task(sendSocketMessage(
+                code=0,
+                msg="开始处理抠图",
+                data={
+                    "status": "进行中",
+                    "goods_art_nos": goods_arts,
+                },
+                msg_type="segment_progress",
+            ))
+        except:
+            print('An exception occurred')
+            asyncio.run(sendSocketMessage(
+                code=0,
+                msg="开始处理抠图",
+                data={
+                    "status": "进行中",
+                    "goods_art_nos": goods_arts,
+                },
+                msg_type="segment_progress",
+            ))
         if do_next:
             all_goods_art_no_folder_data = [
                 x for x in all_goods_art_no_folder_data if x["label"] == "待处理"
@@ -286,7 +299,7 @@ class RunMain:
             print("===============all_goods_art_no_folder_data===============")
             print(all_goods_art_no_folder_data)
 
-            new_func = await self.do_run_cutout_image(
+            new_func = self.do_run_cutout_image(
                 all_goods_art_no_folder_data=all_goods_art_no_folder_data,
                 callback_func=self.show_progress_detail,
                 image_order_list=return_data["data"]["image_order_list"],
@@ -299,18 +312,35 @@ class RunMain:
             return new_func
         else:
             print("已结束抠图处理")
-            await sendSocketMessage(
-                code=0,
-                msg="抠图结束",
-                data={
-                    "status": "已完成",
-                    "goods_art_nos": goods_arts,
-                },
-                msg_type="segment_progress",
-            )
+            try:
+                loop = asyncio.get_event_loop()
+                loop.create_task(
+                    sendSocketMessage(
+                        code=0,
+                        msg="抠图结束",
+                        data={
+                            "status": "已完成",
+                            "goods_art_nos": goods_arts,
+                        },
+                        msg_type="segment_progress",
+                    )
+                )
+            except:
+                print('An exception occurred')
+                asyncio.run(
+                    sendSocketMessage(
+                        code=0,
+                        msg="抠图结束",
+                        data={
+                            "status": "已完成",
+                            "goods_art_nos": goods_arts,
+                        },
+                        msg_type="segment_progress",
+                    )
+                )
             return True
 
-    async def do_run_cutout_image(
+    def do_run_cutout_image(
         self,
         all_goods_art_no_folder_data,
         callback_func,
@@ -321,21 +351,43 @@ class RunMain:
         logo_path,
         config_data,
     ):
+        try:
+            loop = asyncio.get_event_loop()
+        except:
+            loop = asyncio.new_event_loop()
+        executor = ThreadPoolExecutor(max_workers=4)
         goods_arts = [
             goods_art_no_folder_data["folder_name"]
             for goods_art_no_folder_data in all_goods_art_no_folder_data
         ]
         print("BaseDealImage().run_main========>>>>")
         deal = BaseDealImage(token=self.token)
-        await deal.run_main(
-            all_goods_art_no_folder_data=all_goods_art_no_folder_data,
-            callback_func=callback_func,
-            image_order_list=image_order_list,
-            cutout_mode=cutout_mode,
-            resize_image_view=resize_image_view,
-            windows=windows,
-            logo_path=logo_path,
-        )
+        try:
+            loop.run_in_executor(
+                executor,
+                deal.run_main(
+                    all_goods_art_no_folder_data=all_goods_art_no_folder_data,
+                    callback_func=callback_func,
+                    image_order_list=image_order_list,
+                    cutout_mode=cutout_mode,
+                    resize_image_view=resize_image_view,
+                    windows=windows,
+                    logo_path=logo_path,
+                ),
+            )
+        except UnicornException as e:
+            raise UnicornException(e.msg)
+        except Exception as e:
+            raise UnicornException(e)
+        # deal.run_main(
+        #     all_goods_art_no_folder_data=all_goods_art_no_folder_data,
+        #     callback_func=callback_func,
+        #     image_order_list=image_order_list,
+        #     cutout_mode=cutout_mode,
+        #     resize_image_view=resize_image_view,
+        #     windows=windows,
+        #     logo_path=logo_path,
+        # )
 
         recordDataPoint(
             token=self.token,
@@ -343,15 +395,31 @@ class RunMain:
             page="抠图结束",
             data=goods_arts,
         )
-        await sendSocketMessage(
-            code=0,
-            msg="抠图结束",
-            data={
-                "status": "已完成",
-                "goods_art_nos": goods_arts,
-            },
-            msg_type="segment_progress",
-        )
+        try:
+            loop = asyncio.get_event_loop()
+            loop.create_task(
+                    sendSocketMessage(
+                        code=0,
+                        msg="抠图结束",
+                        data={
+                            "status": "已完成",
+                            "goods_art_nos": goods_arts,
+                        },
+                        msg_type="segment_progress",
+                    )
+                )
+        except:
+            asyncio.run(
+                sendSocketMessage(
+                    code=0,
+                    msg="抠图结束",
+                    data={
+                        "status": "已完成",
+                        "goods_art_nos": goods_arts,
+                    },
+                    msg_type="segment_progress",
+                )
+            )
         callback_func("已结束抠图处理")
         return True
 

+ 1 - 0
python/settings.py

@@ -5,6 +5,7 @@ import configparser, json, pytz
 import requests
 import pillow_avif
 from utils.common import message_queue
+import hashlib
 
 TIME_ZONE = pytz.timezone("Asia/Shanghai")
 from numpy import true_divide

+ 17 - 3
python/sockets/message_handler.py

@@ -14,14 +14,27 @@ from service.base import check_move_goods_art_no_folder
 from service.deal_image import DealImage
 import settings
 from middleware import UnicornException
+from concurrent.futures import ThreadPoolExecutor
+from functools import partial
 
-
+# 创建全局线程池
+executor = ThreadPoolExecutor(max_workers=4)
 async def handlerCutOut(
     manager=None, run_main=None, config_data={}, websocket=None, msg_type=""
 ):
     try:
-        return_data = run_main.check_before_cutout(config_data)
-        await run_main.check_for_cutout_image_first_call_back(return_data)
+        # return_data = run_main.check_before_cutout(config_data)
+        # await run_main.check_for_cutout_image_first_call_back(return_data)
+        # 将阻塞操作放到线程池中执行
+        loop = asyncio.get_event_loop()
+        return_data = await loop.run_in_executor(
+            executor, partial(run_main.check_before_cutout, config_data)
+        )
+        # await run_main.check_for_cutout_image_first_call_back(return_data)
+        await loop.run_in_executor(
+            executor,
+            partial(run_main.check_for_cutout_image_first_call_back, return_data),
+        )
     except UnicornException as e:
         data = manager.jsonMessage(
             code=1,
@@ -31,6 +44,7 @@ async def handlerCutOut(
         await manager.send_personal_message(data, websocket)
         return
     except Exception as e:
+        print("error",e)
         data = manager.jsonMessage(
             code=1,
             msg="抠图异常,请稍后重试~",