์ผ๋‹จ ํ•˜๊ณ  ๋ณด๋Š” ์‚ฌ๋žŒ

๋‚˜์ค‘๋ณด๋‹จ ์ง€๊ธˆ์— ์ง‘์ค‘ํ•˜๋˜, ์ง€๊ธˆ๋ณด๋‹จ ๋‚˜์ค‘์— ์™„๋ฒฝํ•ด์ง€์ž๐Ÿ’ช๐Ÿป

๐Ÿคš๐Ÿป ๋” ๋‚˜์€ ๊ฐœ๋ฐœ์ž ํ•˜๊ธฐ/โ›๏ธ๐Ÿ’ฆ ์‚ฝ์งˆ๊ธฐ

๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ + ํ + dataclass ๋ฆฌํŒฉํ† ๋ง ์‚ฝ์งˆ๊ธฐ~

JanginTech 2025. 8. 18. 23:29

๐Ÿงฉ ๋ฐฐ๊ฒฝ

์˜ค๋Š˜ ๋“œ๋””์–ด ๋ฆฌํŒฉํ† ๋ง ํ•  ์ˆ˜ ์žˆ๋Š” ํ‹ˆ์ƒˆ์‹œ๊ฐ„์ด ์ฃผ์–ด์ง„ ๋‚ !!

์ตœ๊ทผ ์ฝ”๋“œ ๋ฆฌํŒฉํ† ๋ง ๊ณผ์ •์—์„œ ๋ฐ˜๋ณต๋˜๋Š” ๋กœ์ง(์ฃผ์„์œผ๋กœ ๋ฏธ๋ฆฌ ํ‘œ์‹œํ•ด๋†จ์ง€๋กฑ)์„ ์ •๋ฆฌํ•˜๊ณ  ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ์œผ๋กœ ๋ฌธ์„œ ์ ์žฌ๋ฅผ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ข€ ๋‹ค๋“ฌ์œผ๋ ค๊ณ  ํ–ˆ๋‹ค

 

์šฐ์„  ๋‚ด ์‚ฝ์งˆ ๊ธฐ๋ก ์ „์— ๋‚ด๊ฐ€ ํ•˜๊ณ  ์žˆ๋Š” ๊ณผ์—…์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์„ค๋ช…

1. ๋ฌธ์„œ(html)๋ฅผ ์ฒญํฌ(seq)๋กœ ์ชผ๊ฐœ์„œ ์ ์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์—, response๋Š” ๋ฌธ์„œ ๋‹จ์œ„๋กœ ์„ฑ๊ณต/์‹คํŒจ/๋ฏธ๋ถ„๋ฅ˜๋œ ๋ฌธ์„œ ์ฒญํ‚น ์•„์ด๋”” ๋ฅผ ๋ชจ์•„์ฃผ์–ด์•ผ ํ•œ๋‹ค.

1-1. ๋‹จ์ˆœํžˆ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ช‡ ๊ฐœ ์„ฑ๊ณตํ–ˆ๋Š”์ง€๊ฐ€ ์ค‘์š”ํ•œ ๊ฒŒ ์•„๋‹ˆ๋ผ: 

A๋ฌธ์„œ๋Š” ์ด 3๊ฐœ์˜ ์ฒญํฌ์ค‘ 1๊ฐœ ์„ฑ๊ณต, 2๊ฐœ ์‹คํŒจ
B๋ฌธ์„œ๋Š” ์ด 15๊ฐœ์˜ ์ฒญํฌ์ค‘ 15๊ฐœ ์„ฑ๊ณต, 0๊ฐœ ์‹คํŒจ

์ด๋ ‡๊ฒŒ ๋ฌธ์„œ ์ฒญํฌ ๋‹จ์œ„๋กœ ์ƒํƒœ๋ฅผ ์ง‘๊ณ„ํ•ด์•ผ ๋‚˜์ค‘์— ํ†ต๊ณ„/๋กœ์ง๊ฐ•ํ™” ๋“ฑ์— ์“ฐ์ผ ์ˆ˜ ์žˆ๋‹ค!

 

2. ์—ฌ๊ธฐ์„œ, ์Šค๋ ˆ๋“œ๋ณ„๋กœ ์ฒ˜๋ฆฌ๋˜๋Š” ๋ฌธ์„œ์— ๋Œ€ํ•œ ์„ฑ๊ณต/์‹คํŒจ/๋ฏธ๋ถ„๋ฅ˜๋œ ๋ฌธ์„œ ์ฒญํ‚น ์•„์ด๋””๋ฅผ ๋”ฐ๋กœ ๋ชจ์•„์•ผ ํ–ˆ๊ณ , ์ด๋ฅผ ๋‹ค์‹œ ํ•œ๋ฒˆ ํ•ฉ์ณ์„œ API response ํฌ๋งท์— ๋งž์ถฐ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ–ˆ๋‹ค.

3. ๋‚ด๊ฐ€ ์›ํ•˜๋Š” ํฌ๋งท์€ ์ด๊ฑฐ:

{
  "docLoadResult": {
    "processResults": [
      {
        "docId": "DOC123",
        "successList": ["DOC123_1"],
        "failureList": ["DOC123_2"],
        "unknownList": [],
        "docListCnt": 2
      },
      {
        "docId": "DOC456",
        "successList": ["DOC456_1"],
        "failureList": [],
        "unknownList": ["DOC456_2", "DOC456_3"],
        "docListCnt": 3
      }
    ]
  }
}

 

 

๐Ÿ’ญ ๊ณ ๋ฏผ์˜ ๋‚ด์šฉ

์ฒ˜์Œ์—๋Š” ๋‹จ์ˆœ ๋ฆฌ์ŠคํŠธ ๋ฌถ์Œ์œผ๋กœ ๊ด€๋ฆฌํ–ˆ๋Š”๋ฐ ์ ์  ์ฝ”๋“œ๊ฐ€ ์ง€์ €๋ถ„ํ•ด์ ธ์„œ dataclass๋ฅผ ๋„์ž…ํ•ด ๊ตฌ์กฐํ™”ํ•˜๊ธฐ๋กœ ํ–ˆ๋‹ค.

์š”๋ ‡๊ฒŒ:

from dataclasses import dataclass, field

@dataclass
class ResultDoc:
    docSuccessList: list = field(default_factory=list)
    docFailureList: list = field(default_factory=list)
    docUnknownList: list = field(default_factory=list)
    docListCnt: int = 0

 

1. ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ResultDoc ๊ฐ์ฒด๋ฅผ ์ฑ„์šด๋‹ค

2. queue.put(resultDoc)๋กœ ๊ฒฐ๊ณผ๋ฅผ push ํ•ด์ค€๋‹ค

3. ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋๋‚œ ๋’ค, queue.get()์œผ๋กœ ํ‘ธ์‰ฌํ•ด๋†“์€ ๊ฒฐ๊ณผ๋“ค์„ ๋ชจ์•„ ์ตœ์ข… response๋ฅผ ๋งŒ๋“ค์–ด ์ตœ์ข… return!

 

 

๊ทธ๋Ÿฌ๋‚˜

๋ฌธ์ œ๋Š” ๊ฒฐ๊ณผ ์ง‘๊ณ„๋ฅผ ๋‹ค๋ฃจ๋Š” ๊ณผ์ •์—์„œ ๋ฐœ์ƒํ–ˆ๋‹ค:

  • ์Šค๋ ˆ๋“œ๋ณ„๋กœ ResultDoc ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค์–ด ํ์— ๋„ฃ์—ˆ๋Š”๋ฐ successList์— ๊ฐ’์ด ์•ˆ ๋“ค์–ด๊ฐ ๐Ÿ’ข(๋งน์ƒˆ์ฝ” ๋ถ„๋ช… ๋””๋ฒ„๊น…ํ–ˆ์„ ๋• ์ž˜ ๊ฐ–๊ณ  ์™”๋˜ ๊ฐ’๋“ค์ด์—ˆ๋‹ค ใ…œใ…œ)
  • count๊ฐ’(๊ฐ๋ฌธ์„œ๋ณ„ ๋ฌธ์„œ ์ฒญํฌ ๋ฐ์ดํ„ฐ ์นด์šดํŠธ)์€ ์ž˜ ์ฐํžˆ๋Š”๋ฐ ์™œ ๋ฆฌ์ŠคํŠธ๋Š” ๋น„์–ด์žˆ๋Š” ๊ฑฐ์ง€? ๋Œ€์ฒด ์–ด๋””์„œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋‚ ์•„๊ฐ„ ๊ฑด์ง€,,
  • ํŠนํžˆ ๋””๋ฒ„๊น… ๋ชจ๋“œ์—์„  ๋ฆฌ์ŠคํŠธ ์•ˆ ๊ฐ’์ด ๋ณด์ด๋Š”๋ฐ!!! ์™œ response๋กœ ๋งŒ๋“ค์–ด ๋‚ด๋ณด๋‚ด๋ฉด ํ•˜์—ผ์—†์ด []๋งŒ ๋‚˜์˜ค๋Š” ๊ฒƒ์ด๋ƒ ๋Œ€์ฒด ์™œ..

์ด ๊ณผ์ •์—์„œ ๋‚˜๋Š”

'๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์ด๋ผ ๊ฐ’์ด ๊ผฌ์˜€๋‚˜?'

'์ „์—ญ๋ณ€์ˆ˜ ๋ฌธ์ œ์ธ๊ฐ€?' (๊ดœํžˆ ์˜์‹ฌ)

๊ฐ™์€ ๋ถˆ์•ˆ๊ฐ์ด ์ปค์กŒ๊ณ  ์›์ธ์„ ํ•œ์ฐธ ๋ชป ์žก์œผ๋‹ˆ ๋„ˆ๋ฌด๋„ˆ๋ฌด ๋‹ต๋‹ตํ–ˆ๋‹ค.

 

 

๐Ÿ› ๏ธ ํ•ด๊ฒฐ์„ ์œ„ํ•œ ์‹œ๋„๋“ค

์˜ค๋Š˜ ํ•˜๋ฃจ ์ข…์ผ ๊ตฌ๊ธ€๊ณผ GPT๋ฅผ ์˜†๊ตฌ๋ฆฌ์— ๋ผ๊ณ  ์‚ด์•˜๋‹ค.

 

1. deepcopy ์ ์šฉ

์ฐพ์•„๋ณด๋‹ˆ, mutable ๊ฐ์ฒด(list) ์ฐธ์กฐ ๋ฌธ์ œ ์ผ ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•˜๋”๋ผ.

queue.put(copy.deepcopy(resultDoc)) ์„ ํ–ˆ๋‹ค

 

2. dataclass ๊ธฐ๋ณธ๊ฐ’ ํ™•์ธ

ํ˜น์‹œ ๋ชจ๋ฅด๋‹ˆ dataclass ๊ธฐ๋ณธ๊ฐ’์„ field(default_factory=list) ๋กœ ํ•ด์ฃผ์—ˆ๋Š”์ง€ ๋‹ค์‹œ ํ™•์ธํ–ˆ๋‹ค(list = []๊ณผ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ์ผ์„๊นŒ ๋ด)

 

3. ํ์— ๊ฐ’์„ ๋„ฃ๊ธฐ ์ง์ „/์งํ›„ ๋””๋ฒ„๊น…

ํ์— ๋„ฃ๊ธฐ ์ง์ „ ๊ฐ’ → ํ์—์„œ ๊บผ๋‚ธ ์งํ›„ ๊ฐ’ → response์— append ์งํ›„ ๊ฐ’์„ ๋”๋“ฌ๋”๋“ฌ ์ฝ์—ˆ๋‹ค. ๊ทผ๋ฐ ๊ฐ’์„ ์ž˜ ๋“ค๊ณ  ๋‚˜์™”๋Š”๋ฐ..

 

4. ์—ฌ๋Ÿฌ ๊ฐ€์„ค ์„ธ์šฐ๊ธฐ: ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ race condition, ์ „์—ญ ๊ณต์œ  ๋ฌธ์ œ?

 

๊ทผ๋ฐ ๋ฌธ์ œ๋Š” ์ „ํ˜€ ๋‹ค๋ฅธ ๊ณณ์— ์žˆ์—ˆ๋‹ค.

 

 

๋ฐ”๋กœ ์˜คํƒ€ ๐Ÿ˜‚ ๐Ÿ˜‚ ๐Ÿ˜‚ .

ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹ใ…‹

์“ฐ๊ณ ๋„ ์–ด์ด์—†๋‹ค.

 

๊ทธ ๋ฌธ์ œ์˜ ์ฝ”๋“œ ์ •ํ™•ํžˆ ๊ฐ€์ ธ์˜ค๊ฒ ๋‹ค:

final_result.append({
    "successList": list(r.docSuccessList),
    "failureList": list(r.docFailureList),
    "successList": list(r.docUnknownList),  # <- ์ž˜๋ชป๋œ ํ‚ค ์ค‘๋ณต
    "docListCnt": r.docListCnt
})

๋ฐ”๋กœ๋ณด์ด๋‚˜์š”..?

์ „ ์•ˆ ๋ณด์—ฌ์„œ ๋ฐ˜๋‚˜์ ˆ์„ ๋‚ ๋ ธ์Šต๋‹ˆ๋‹ค,,ใ…‹ใ…‹ใ…‹

 

dict ์ƒ์„ฑ ์ฝ”๋“œ์— ๊ฐ™์€ key๋ฅผ ๋‘ ๋ฒˆ ์ผ๊ณ  ๊ฒฐ๊ตญ successList์— unkownList ๊ฐ’์ด ๋‹ด๊ธด ๊ฒƒ์ด๋‹ค.

๊ทธ๋Ÿฌ๋‹ˆ ์›ํ•˜๋Š” ๊ฐ’์ด ๋“ค์–ด๊ฐ€์ง€ ์•Š์•˜๋˜ ๊ฒƒ.

๋ฌธ์ œ์˜ ๋ณธ์งˆ์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋„, ํ๋„, dataclass๋„ ์•„๋‹ˆ์—ˆ๋‹ค.

๊ฒฐ๊ตญ ์˜คํƒ€ ๋ฌธ์ œ์˜€๋‹ค.

 

 

๐Ÿ“ˆ ๋ณ€ํ™”

1. ๊ฐ€์žฅ ํฐ ๋ณ€ํ™”๋Š” ์ด๋ฒˆ ๊ฒฝํ—˜์œผ๋กœ ์ธํ•ด “๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ์›์ธ๋ถ€ํ„ฐ ํ™•์ธํ•˜๋ผ”๋Š” ๊ตํ›ˆ์„ ์–ป์€ ๊ฒƒ์ด ๋˜๊ฒ ๋‹ค.

2. ์˜คํƒ€ ์ˆ˜์ •ํ•ด์„œ ์›ํ•˜๋Š” API ์‘๋‹ต ํ˜•ํƒœ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค

 

 

๐Ÿ“Œ ํšŒ๊ณ  & ๋‹ค์Œ ๋ชฉํ‘œ

  • ๋ณต์žกํ•œ ๋ฌธ์ œ๋ฅผ ์˜์‹ฌํ•˜๊ธฐ ์ „์— ๋‹จ์ˆœํ•œ ์‹ค์ˆ˜๋ฅผ ๋จผ์ € ์ฒดํฌํ•˜์ž
  • ์ด๋ฒˆ ๊ฒฝ์šฐ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ, ํ ์ž์ฒด์˜ ๋ฌธ์ œ์™€๋Š” ๋ฌด๊ด€ํ–ˆ๋Š”๋ฐ.. ๊ดœํžˆ ๊นŠ์€ ๊ณณ๋งŒ ํŒŒ๋‹ค๊ฐ€ ์‹œ๊ฐ„์„ ๋‚ ๋ฆฐ๊ฒƒ์ด๋‹ˆ.. ๊ทธ๋ž˜๋„ ์ด๊ฒŒ ๋‚˜ํ•œํ…Œ ๋„์›€์ด ๋  ๊ฑฐ๋ผ ๋ฏฟ๋Š”๋‹ค. ์ €๋Ÿฐ ๋‚ ๋„ ์žˆ์œผ๋ฉด ์ด๋Ÿฐ ๋‚ ๋„ ์žˆ๋Š” ๊ฑฐ์ง€
  • ๊ทธ๋ ‡๊ฒŒ ๋˜๋ฉด dataclass + queue + ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๊ตฌ์กฐ ์ž์ฒด๋Š” ๊ฝค ๊น”๋”ํ•˜๊ฒŒ ๋งž์•˜๋‹ค๋Š” ๊ฑฐ๊ฒ ์ง€? ์•ž์œผ๋กœ ์Šค๋ ˆ๋“œ ์ฒ˜๋ฆฌํ•  ๋•Œ ํฐ ๋„์›€์ด ๋˜๊ฒ ๋‹ค..
  • ๋‹ค์Œ์—๋Š” ์ด๋Ÿฐ ๊ฒฝํ—˜์„ ๋ฐ”ํƒ•์œผ๋กœ, ๋กœ๊น…/ํ…Œ์ŠคํŠธ ์ฝ”๋“œ๋ฅผ ๊ฐ•ํ™”ํ•ด “๋‹จ์ˆœํ•œ ์‹ค์ˆ˜”๊ฐ€ ์ด๋ ‡๊ฒŒ ํฐ ์‚ฝ์งˆ๋กœ ์ด์–ด์ง€์ง€ ์•Š๊ฒŒ ํ•˜๊ณ  ์‹ถ๋‹ค.