rokdocs
v0.1

9.8. Jupyter 커널 통합

Jupyter 표면 의 rok 커널을 정의합니다.

9.8.1. 커널

Jupyter 가 rok 커널을 별도 프로세스로 실행하며, ZeroMQ 기반 Jupyter wire protocol 로 통신합니다. 커널은 protocol_version 을 "5.3" 으로 알립니다 (jupyter_client 가 기대하는 값, 5.3 이상의 클라이언트와 동작). 이 형태에서는 OS 자원, 즉 파일과 네트워크와 외부 프로세스를 모두 사용할 수 있습니다.

커널은 터미널 REPL 과 같은 셀 세션 위에서 동작하며 9.7.0 의 규칙을 따릅니다. 각 셀은 한 번만 실행되고, 바인딩과 항목은 이후 셀로 이어지며, 실패한 셀은 바인딩에 흔적을 남기지 않습니다. 커널의 엔진은 REPL 과 같은 JIT 세션 입니다.

노트북 셀과 REPL 셀

노트북 셀 하나는 터미널 REPL 이 입력을 나누는 것과 같은 규칙으로 REPL 셀 여러 개로 나뉘어 차례로 실행됩니다. 결과로는 IPython 처럼 마지막 값만 표시합니다. 노트북 셀의 뒷부분이 실패하면, 앞부분 (앞선 REPL 셀) 의 효과는 그대로 남습니다.

9.8.2. 로컬 네이티브 커널: 동작

사용자가 노트북의 kernel 로 "rok" 를 고르면 Jupyter 가 kernelspec (9.8.3) 의 명령을 별도 프로세스로 실행합니다.

rokc jupyter --connection-file <path>       # --extern 등 rokc 옵션도 받음
rok jupyter --connection-file <path>        # 의존성을 해소한 뒤 rokc jupyter 를 실행

커널은 connection file 의 ZMQ port 와 key 를 읽고 다섯 소켓에 bind 해 listen 합니다. 다섯 소켓이 모두 연결을 받을 수 있게 되면, 출력 캡처를 시작하기 전에 stderr 에 rokc jupyter: ready 한 줄을 씁니다. 전송은 tcp 만 지원하며 (ipc 없음), CURVE 암호화는 쓰지 않습니다. 메시지는 connection file 의 key 로 HMAC 서명합니다.

소켓 채널

채널용도
shell요청 (execute, kernel_info, complete, is_complete 등)
iopub출력과 상태 broadcast (status, stream, execute_result 등)
stdin쓰지 않음 - 입력 요청을 보내지 않음 (stdin 은 /dev/null)
controlinterrupt, shutdown
heartbeat받은 것을 그대로 돌려보냄 (echo)

메시지 형식

각 메시지는 6 개 이상의 ZMQ frame 으로 직렬화됩니다.

[b"u-u-i-d",         # zmq identity(ies)
 b"<IDS|MSG>",       # delimiter
 b"baddad42",         # HMAC 서명 (key 로)
 b"{header}",          # 헤더 JSON
 b"{parent_header}",   # 부모 헤더 JSON
 b"{metadata}",        # 메타데이터 JSON
 b"{content}",         # 콘텐츠 JSON
]

자세한 형식은 Jupyter wire protocol 표준 문서를 따릅니다. 모든 요청은 iopub 의 status: busy 와 status: idle 로 감쌉니다.

지원하는 메시지

요청응답
kernel_info_requestlanguage_info 의 name rok, mimetype text/x-rok, file_extension .rok, protocol_version "5.3"
execute_request아래 "실행" 참조
is_complete_requestREPL 의 이어 쓰기 규칙으로 complete / incomplete 판정
complete_request세션의 이름, 멤버, 키워드를 후보로 (9.8.5)
inspect_request커서의 이름에 대한 text/plain 도움말과 found: true (9.8.6), 아니면 false
history_request이 커널이 실행한 셀들
comm_info_request빈 목록
shutdown_requestshell 이나 control 에서. 응답 후 종료
interrupt_requestcontrol 에서 (9.8.4)

실행

execute_request 를 받으면 다음을 보냅니다.

  1. iopub execute_input (코드와 실행 번호).
  2. 셀이 끝난 뒤 그 출력: stdout / stderr 는 iopub stream 으로. 실행 중에 조금씩 보내지 않습니다.
  3. 값이 있으면 iopub execute_result: text/plain 에 REPL 과 같은 타입: 값 (9.7.7).
  4. 실패하면 iopub error: evalue 는 stderr 의 첫 줄, traceback 은 stderr 의 줄들.
  5. shell execute_reply (execution_count 포함, 성공 / 실패 status).

출력 MIME 은 text/plain 하나입니다.

9.8.3. kernelspec 설치

Jupyter 는 kernelspec 디렉토리에 설치된 kernel 만 인식합니다.

rok jupyter install [--env <name>]

kernelspec 은 다음 디렉토리 아래의 kernels/rok/kernel.json 입니다. --env <name> 으로 설치하면 kernels/rok-<name>/ 이며, 표시 이름은 rok (<name>), 실행 명령은 rok --env <name> jupyter ... 입니다.

  1. $JUPYTER_DATA_DIR 이 있으면 그 디렉토리
  2. macOS 이면 ~/Library/Jupyter
  3. 그 밖에는 $XDG_DATA_HOME/jupyter, 없으면 ~/.local/share/jupyter

kernel.json 은 rok proxy (9.10.6) 를 실행하며, 설치 때의 ROK_HOME 과 PATH 를 env 에 기록합니다.

{
  "argv": ["/home/u/.rok/bin/rok", "jupyter", "--connection-file", "{connection_file}"],
  "display_name": "rok",
  "language": "rok",
  "interrupt_mode": "message",
  "env": { "ROK_HOME": "/home/u/.rok", "PATH": "<설치 때의 PATH>" }
}

이렇게 설치하고 나면 Jupyter, VS Code, nteract 등 어디서든 rok 커널을 사용할 수 있습니다.

9.8.4. 인터럽트 / 종료

인터럽트

interrupt_mode 가 "message" 이므로 인터럽트는 control 소켓의 interrupt_request 로 옵니다. 실행 중인 셀을 끝내고, 세션은 그 셀 이전의 상태로 계속됩니다 (실패한 셀과 같음, 9.7.0). 아직 컴파일 중인 셀은 인터럽트할 수 없습니다.

종료 (kernel restart)

shell 이나 control 소켓의 shutdown_request 에 응답한 뒤 세션을 정리하고 프로세스를 종료합니다. restart 의 경우에는 Jupyter 가 자동으로 다시 띄워 줍니다.

9.8.5. 코드 자동 완성

complete_request 는 커서 앞의 조각을 세션의 바인딩, 항목, 모듈 경로, 멤버, 키워드에 맞춰 { matches, cursor_start, cursor_end } 로 응답합니다.

9.8.6. inspect_request: 도움말

inspect_request (Shift+Tab) 는 found: true 와 함께, 커서의 이름을 name: type 으로, 그리고 그 시그니처와 문서 주석 (어휘 구조 의 /// / //!) 을 text/plain 으로 응답합니다. 모르는 이름이면 found: false 입니다.

9.8.7. REPL 과 Jupyter 의 코드 공유

REPL 에서 작성한 코드는 그대로 Jupyter 셀로 옮길 수 있고, 반대 방향도 마찬가지로 가능합니다. 같은 셀 세션과 같은 의미론 (9.7.0) 을 따르고 있기 때문입니다.

차이

다만 양쪽 표면 사이에는 몇 가지 차이가 존재하며, 다음 표에 정리합니다.

측면REPLJupyter
입력한 줄 / 한 식한 셀 (여러 줄)
출력text onlytext (text/plain)
상태 보존종료 시 폐기노트북 파일에 셀 보존

9.8.8. 보안 / 격리

커널은 사용자 권한으로 임의 코드를 실행합니다. 격리는 하지 않습니다.

9.8.9. 다음

이어지는 디버그 / 진단 도구 에서는 gdb 친화 기능과 profile, --emit 등을 정의합니다.

GitHub에서 이 페이지 고치기