λ€λ₯Έ λκ΅°κ°κ° μμνμ¬ μ΄κ²μ νλ κ²½μ°μ λν΄ μ μκ² λ¬Όμ΄λ³΄μΈμ :)
κ°μ ν¬μ€ν μ νλ¬ μμ΅λλ€. λλ κΈ°κΊΌμ΄ νμ§λ§ λ§ κ·Έλλ‘ C νμ₯μ λν κ²½νμ΄ μμ΅λλ€. μ κ° λμμ΄ λ μ μλ€λ©΄ μλ €μ£ΌμΈμ. 2μμ 3μΌλ‘μ ν¬ν νμ₯μ μ€λͺ νλ μ μ ν λꡬλ λ¬Έμλ₯Ό μλ €μ£Όμ€ μ μλ€λ©΄ κ·Έκ²μ μμ λΆμ΄ νμ΄μ μνν΄ λ³΄κ² μ΅λλ€.
μ΄μν΄μΌ ν κ²μ΄ λ§μ§ μμΌλ―λ‘ λ무 μ΄λ ΅μ§ μμμΌ ν©λλ€.
PyString_foo
κ° Py3μμ μ¬λΌμ‘μΌλ―λ‘ κΈ°λ³Έ λ¬Έμμ΄ μ ν(WSGI dict ν€/κ°)μ λν 맀ν¬λ‘λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
λν μΌλ°μ μΈ Py2-to-Py3 μ΄μ λμλ§μ http://rhodesmill.org/brandon/2008/porting-ac-extension-module-to-python-30/ μ μ°Έμ‘°νμμμ€.
μ§λ¬Έμ΄ μμΌμλ©΄ μΈμ λ μ§ μ΄λ©μΌμ 보λ΄μ£ΌμΈμ :)
κΈ°λ‘μ μν΄ λ€μμ PEP 333μμ PEP 3333μΌλ‘μ μ°¨μ΄μ λλ€. http://paste.pocoo.org/show/320496/
μ£μ‘ν©λλ€λ§, μ νΌμμλ μ΄ μΌμ ν΄λΌ μ μμ κ²μ λλ€. μ¬κΈ°μμ λκ΅°κ°μκ² λμμ΄ λ μ μκΈ°λ₯Ό λ°λλλ€. λλ λ¨μν Cλ₯Ό λͺ¨λ₯Έλ€.
λ΄ ν¬ν¬μ νμ¬ μν μ½λλ vPy2κ° μν₯μ λ°μ§ μκ³ (μλ) μ μ§λκ³ vPy3μ΄ μ΅μν μ΄κΈ°νλ μ μλλ‘ μ»΄νμΌλ©λλ€. μ΄ backtrace μ λ°λΌ 첫 λ²μ§Έ μμ²μ ν λ segfaultλ₯Ό μμ ν©λλ€.
http://docs.python.org/py3k/howto/cporting.html μ λ€μμ λν λ³κ²½ μ¬νμ μ€λͺ ν©λλ€.
$ request.c
$ μμ PyInt_FromLong
μμ PyLong_FromLong
λ‘ μ΄λν΄μΌ νλ λ κ°μ§ μΈμ€ν΄μ€κ° μλ ν μ€μ΄ μμ΅λλ€.
μ΄λ¬ν μ μ λ PyString
μ λͺ¨λ μΈμ€ν΄μ€λ₯Ό ν¬ν¨ν΄μΌ ν©λλ€.
http://docs.python.org/py3k/c-api/module.html μ λ μμΈν μ 보λ₯Ό μ 곡ν©λλ€.
request.c
μ cStringIO
λ νμ€ PyBytes
λ‘ λ체λμ΄μΌ νλ€κ³ μκ°ν©λλ€.
νλμ cString ν¨μ λμ memcpy
μ μ¬μ©νκ³ λ¨μν wsgi.input
λ₯Ό μ²λ¦¬νλ λ°©λ²μ λͺ°λμ΅λλ€. PycString_IMPORT
μ λν νΈμΆμ΄ κ΅μ²΄ μμ΄ μ κ±°λμμ΅λλ€.
λͺ¨λ μ΄κΈ°ν: μ μ λ§ μΆνλ€μ :-( κ·Έλ€μ μ μ΄λ μ°λ¦¬μκ² μ§μ€μ μ¨κΈ°λ 루ν΄μ μ 곡νμ μ μμ΅λλ€ :-(
λ¬Έμμ΄: Py3μ ν€λ νλͺ©μλ PyUnicode
λ₯Ό, Py2μμλ PyString
λ₯Ό μ¬μ©ν΄μΌ νλ©°, Py3μμλ PyBytes
λ₯Ό μ¬μ©ν΄μΌ ν©λλ€. PEP 3333 diffλ₯Ό μ½μμ΅λκΉ?
cStringIO: μ’μ μκ°μ λλ€. μ€μ λ‘ cStringIOλ₯Ό μ¬μ©νλ μ΄μ λ₯Ό μ ν λͺ¨λ₯΄κ² μ΅λλ€(λ΄μ© κΈΈμ΄κ° μλ €μ Έ μμΌλ―λ‘ μ μ λ¬Έμμ΄ κ°μ²΄λ‘ μΆ©λΆν΄μΌ ν¨). κ·Έλ¬λ cStringIOλ WSGI μμ© νλ‘κ·Έλ¨μ νΈμΆνκΈ° μ μ νμΌκ³Ό κ°μ΄ λ³νλμ΄μΌ νλ―λ‘ Py3 cStringIO λ체ν(무μμ΄λ κ°μ)μ μ¬μ©νκ±°λ μ체 λνΌλ₯Ό λ‘€μμν©λλ€(μ λ κ·Έλ κ² ν μ μμ΅λλ€).
btw segfaultλ μμ² λ³Έλ¬Έμ΄ μκΈ° λλ¬Έμ μ λ¬λ μΈμκ° NULL ν¬μΈν°μ΄κΈ° λλ¬Έμ λλ€.
λͺ¨λ μ΄κΈ°ν: μ μ λ§ μΆνλ€μ :-( κ·Έλ€μ μ μ΄λ μ°λ¦¬μκ² μ§μ€μ μ¨κΈ°λ 루ν΄μ μ 곡νμ μ μμ΅λλ€ :-(
μ, < 1KLOCλ λμμ΄ λμ§ μμ΅λλ€. μ€μ λ‘ μμ©κ΅¬μ λ§μ λΆλΆμ μ κ±°νλλ° κ·Έλ κ² λλΉ λ³΄μ΄μ§λ μμ΅λλ€.
λ¬Έμμ΄: Py3μ PyBytesκ° μλλΌ Py3μ ν€λ νλͺ©μ PyUnicodeλ₯Ό μ¬μ©νκ³ Py2μ PyStringμ μ¬μ©ν΄μΌ ν©λλ€. PEP 3333 diffλ₯Ό μ½μμ΅λκΉ?
μ, μΆ©λΆν μ’μ§ μμ΅λλ€. λλ μ€μ λ‘ κ³΅μ diff λ₯Ό μ¬μ©νκ³ λ
Έλμμμ κΈΈμ μμμ΅λλ€. κ±°μ λͺ¨λ κ²μ΄ λ°μ΄νΈ λ¬Έμμ΄μ λνλ
λλ€. λ€κ° μ³μ. λ°©κΈ μ μ ν λͺ¨λ μ½λλ₯Ό PyBytes λ° PyUnicodeλ‘ κ΅μ²΄νκ³ define
dλ₯Ό Py2xμ© PyStringμΌλ‘ λ°κΏ¨μ΅λλ€. environ
λ°/λλ ν€λλ₯Ό μ΄μ κ°μ΄ μ²λ¦¬ν΄μΌ ν©λκΉ? HTTP/1.1 400 Bad Request
PyUnicode_FromString
λ₯Ό μ¬μ©ν λ telnetμ μ°λ κΈ°λ₯Ό λ±μ§λ§ PyBytes_FromString
λ μ μλν©λλ€.
Googleμ μ¬μν μμΈμ ν¨κ» μ°Έμ‘°λλ cStringIO λ° Python3μ μ°Ύμ§ λͺ»ν©λλ€. μ¬κΈ° νλ κ° μμ΅λλ€. λ°©κΈ μμ ν μ κ±°νμ΅λλ€
κ·Έκ²μ μλͺ»λ segfaultμμ΅λλ€. μ£μ‘ν©λλ€. λλ μ΄λ―Έ μ μ΄λ κ·Έ μΆμ²λ₯Ό μΆμ νμ΅λλ€. μ΄κ²μ wsgi_app
κ° νΈμΆ κ°λ₯νμ§ μλ€κ³ λΆννμ¬ λ΄κ° μ€ν κ°λ₯ν μλ²μ κ°κΉλ€κ³ μκ°νκ² ν©λλ€. κ·Έκ²μ μμλΌ μ μλ€λ©΄ μΈμ½λ© λ¬Έμ λ₯Ό λ μ ν΄κ²°ν μ μμ κ²μ
λλ€.
λ€μ΄ν°λΈ λ¬Έμμ΄/μ λμ½λ λ¬Έμμ΄μ μ‘°κΈμ© λ§μ³ λμλ€κ³ μκ°ν©λλ€. κ·Έλμ μ¬κΈ°μ λͺ κ°μ§ νμ΄ μμ΅λλ€.
λ κ°μ ν€λ νμΌ py2.h
λ° py3.h
, #defining λͺ¨λ _used_ PyStr_*
루ν΄μ Python λ²μ μ κΈ°λ³Έ λ°μ΄ν° μ ν( str
, = PyString
Py2μ PyUnicode
). κ·Έλ° λ€μ PyBytes_*
맀ν¬λ‘λ₯Ό Py2μμ PyString
λ‘ μ μν©λλ€(Py2μ str
κ° Py3μ bytes
μ΄κΈ° λλ¬Έμ). PyUnicode
λ PEP 3333μ΄ κ°μ‘°νλ κ²μ²λΌ Python 2λ₯Ό μ¬μ©νμ¬ μ ν μ¬μ©λμ§ μμ΅λλ€.
μλ΅μ νμ PyBytes
μ¬μΌ ν©λλ€. Python 2μμλ PyString
κ° λ°μ΄νΈμ΄λ―λ‘ μΈμ½λ©μ μνν νμκ° μμ§λ§ Python 3μμλ WSGI μμ© νλ‘κ·Έλ¨μ΄ PyUnicode
. νμ©λλ κ²½μ° ν΄λΉ μ λμ½λ λ¬Έμμ΄μ μ΄λ»κ²λ μΈμ½λ©λμ΄μΌ ν©λλ€. νμ§λ§ μ΄λ€ μΈμ½λ©μ μ νν΄μΌ ν μ§ λͺ¨λ₯΄κ² μ΅λλ€.
κ·νμ segfaultλ λ§€μ° μ΄μν©λλ€. λλ λΉμ μ΄ λ€λ₯Έ κ³³μμ refcountλ₯Ό μλ§μΌλ‘ λ§λ κ² κ°μ΅λλ€ ... λͺ¨λκ° κ±±μ νμ§ λ§μμμ€ :)
on_body
μ λν λͺ¨λ νΈμΆμ΄ μ΄μ μ μμ λ λ°μ΄ν°λ₯Ό μ¬μ μνκΈ° λλ¬Έμ νμ¬ cStringIO λ체( memcpy
μ¬μ©)κ° μ€λ¨λμμ΅λλ€. memcpy
ed λ°μ΄ν°μ μ΄λμ μΆμ ν΄μΌ ν©λλ€( bjparser
ꡬ쑰체 νμ₯). λν body = FromString(body)
(203ν)μ λΆνμνκ³ μ 체 λ³Έλ¬Έ 볡μ¬λ₯Ό μννκΈ° λλ¬Έμ μ κ±°ν©λλ€.
λ Έλ ₯ν΄ μ£Όμ μ λλ¨ν κ°μ¬ν©λλ€!
μλ νμΈμ Angelo, Py3 μ§μμ λν μμμ΄ μμ΅λκΉ?
ν! μ‘°λ§κ° μ΄λ₯Ό λΆνμν¬ κ³νμ΄ μμ΅λκΉ? κ·Έλ μ§ μμΌλ©΄ μ°λ¦΄ μλ μμ΅λλ€.
μλ, κ³νμ΄ μμ΅λλ€. https://github.com/isaiah/bjoern-py3 λ€λ₯Έ μ¬λμ΄ λ§λ ν¬νΈκ° μμ§λ§ ν μ€νΈν μ μ΄ μμΌλ©° λ무 λ§μ μ½λ(bytesio κ°μ²΄)λ₯Ό μΆκ°ν©λλ€.
bjoernμ΄ μ¬μ ν SO_REUSEPORT ꡬνμ κ°μ§ μ μΌν WSGI μλ²λΌλ κ²μ μλ €μ£Όλ μ€λλ λ¬Έμ λΆν. μ°λ¦¬κ° κ·Έκ²μ μ¬μ©ν μ μλ€λ κ²μ΄ μ κ°μ λλ€.
νμ€ν©λκΉ? μ΄κ²μ λͺ¨λ μλ²κ° ꡬνν΄μΌ νλ νμ€ κΈ°λ₯μ λλ€.
μ΄λ¬ν μλ² μ€ μΌλΆλ₯Ό μ¬μ©νλ©΄ μ΄λ―Έ μ΄λ¦° μμΌμ μ λ¬ν μ μμ§λ§ λλΆλΆμ κ²½μ° λ무 볡μ‘νμ¬ μκ°λ§ ν΄λ ννν κ²μ λλ€.
곡μ νκ² λ§νλ©΄ uWSGIλ μ΄λ€ μμΌλ‘λ μ΄λ₯Ό μ§μνμ§λ§ λ¬Έμκ° λλ₯Ό μ£½μ΄κ³ μμ΅λλ€.
μ΄ νλ‘μ νΈλ₯Ό λ무 λ¦κ² μ°Ύμμ΅λλ€ :-(μ΄ λͺ¨λ μκ° λμ λλ nginx μ£Όλ³μμ μ΄λ€ μΆ€λ μμ΄ κ°λ²Όμ΄ Python μΉ μλ²λ₯Ό κΏκΎΈκ³ μμ΅λλ€. Python3μ λν΄ μ λ§λ‘ κ³νμ΄ μμ΅λκΉ?
μλμ, νμ§λ§ ꡬννκΈ°κ° λ무 볡μ‘ν΄μλ μ λ©λλ€. λ°λΌμ CPython C APIμ λν κ²½νμ΄ μκ±°λ λ°°μ°κ³ μ νλ κ²½μ° μμ λ‘κ² νμμμ€!
μ κΉ, Bjoernμ 2017λ μ Python 3μ μ§μνμ§ μμΌλ©° μ΄ λ¬Έμ κ° μ¬μ ν μ΄λ € μμ΅λκΉ? μ. λλ μ΄κ²μ΄ νλ‘μ νΈμ μ€ν κ°λ₯ν μ΅μ μ΄ μλλΌκ³ μκ°ν©λλ€ :(
@jonashaag λ΄κ° μ§μ΄ λ€κ³ python3μμ μλνλλ‘ λ§λ€μμ΅λλ€ ... μ΄κ²μ΄ λ³ν©νκΈ°μ μΆ©λΆν κΉ¨λνμ§ νμ€νμ§ μμ§λ§ μ견/μ μμ νμν©λλ€. :-)
κ°μ₯ μ μ©ν λκΈ
@jonashaag λ΄κ° μ§μ΄ λ€κ³ python3μμ μλνλλ‘ λ§λ€μμ΅λλ€ ... μ΄κ²μ΄ λ³ν©νκΈ°μ μΆ©λΆν κΉ¨λνμ§ νμ€νμ§ μμ§λ§ μ견/μ μμ νμν©λλ€. :-)
https://github.com/jonashaag/bjoern/pull/104