```python
import base64
source_code = """import sys
import time
import datetime
import random
def print_usage():
\"\"\"스크립트 사용법을 출력합니다.\"\"\"
print("\\n[사용법]")
print("python tip_20_timeout_loop_safety.py [total_iterations] [delay_per_item_seconds] [batch_size] [batch_delay_seconds] [max_runtime_minutes] [simulate_failure_rate]")
print("\\n[파라미터 설명]")
print(" total_iterations (정수, 기본값: 100): 수행할 총 작업 항목 수.")
print(" delay_per_item_seconds (실수, 기본값: 0.1): 각 작업 항목 처리 후 대기할 시간(초).")
print(" batch_size (정수, 기본값: 10): 이 개수만큼 작업 후 batch_delay_seconds 만큼 추가 대기.")
print(" batch_delay_seconds (실수, 기본값: 1.0): batch_size 만큼 작업 후 대기할 시간(초).")
print(" max_runtime_minutes (정수, 기본값: 5): 스크립트의 최대 실행 시간(분). 이 시간을 초과하면 강제 종료.")
print(" simulate_failure_rate (실수, 기본값: 0.1): 작업 실패를 시뮬레이션할 확률 (0.0 ~ 1.0).")
print("\\n[실행 예시]")
print(" 기본값으로 실행: python tip_20_timeout_loop_safety.py")
print(" 500개 작업, 각 0.05초 지연, 50개마다 5초 지연, 최대 10분 실행, 5% 실패율: ")
print(" python tip_20_timeout_loop_safety.py 500 0.05 50 5.0 10 0.05")
print(" 총 작업 수와 최대 실행 시간만 변경: python tip_20_timeout_loop_safety.py 2000 0.1 10 1.0 30 0.1")
print("\\n")
def parse_arguments(args):
\"\"\"
명령줄 인자를 파싱하여 딕셔너리 형태로 반환합니다.
잘못된 인자가 있으면 사용법을 출력하고 None을 반환합니다.
\"\"\"
params = {
"total_iterations": 100,
"delay_per_item_seconds": 0.1,
"batch_size": 10,
"batch_delay_seconds": 1.0,
"max_runtime_minutes": 5,
"simulate_failure_rate": 0.1
}
if len(args) > 1 and args[1].lower() == "help":
print_usage()
return None
if len(args) > 1:
try:
params["total_iterations"] = int(args[1])
if params["total_iterations"] <= 0:
raise ValueError("total_iterations는 0보다 커야 합니다.")
if len(args) > 2:
params["delay_per_item_seconds"] = float(args[2])
if params["delay_per_item_seconds"] < 0:
raise ValueError("delay_per_item_seconds는 0 이상이어야 합니다.")
if len(args) > 3:
params["batch_size"] = int(args[3])
if params["batch_size"] <= 0:
raise ValueError("batch_size는 0보다 커야 합니다.")
if len(args) > 4:
params["batch_delay_seconds"] = float(args[4])
if params["batch_delay_seconds"] < 0:
raise ValueError("batch_delay_seconds는 0 이상이어야 합니다.")
if len(args) > 5:
params["max_runtime_minutes"] = int(args[5])
if params["max_runtime_minutes"] <= 0:
raise ValueError("max_runtime_minutes는 0보다 커야 합니다.")
if len(args) > 6:
params["simulate_failure_rate"] = float(args[6])
if not (0.0 <= params["simulate_failure_rate"] <= 1.0):
raise ValueError("simulate_failure_rate는 0.0과 1.0 사이여야 합니다.")
except ValueError as e:
print(f"\\n[오류]: 잘못된 인자 값입니다. {e}")
print_usage()
return None
except IndexError:
pass
return params
def simulate_task(item_id, failure_rate):
\"\"\"
단일 작업 항목을 시뮬레이션합니다.
실제 환경에서는 이 함수를 실제 비즈니스 로직으로 대체하세요.
\"\"\"
print(f" [작업 시작] 항목 {item_id} 처리 중...", end=\"\")
if random.random() < failure_rate:
print(f" [실패] 항목 {item_id} 처리 실패.")
return False
else:
print(f" [성공] 항목 {item_id} 처리 완료.")
return True
def main():
\"\"\"메인 스크립트 실행 로직입니다.\"\"\"
params = parse_arguments(sys.argv)
if params is None:
sys.exit(1)
total_iterations = params["total_iterations"]
delay_per_item_seconds = params["delay_per_item_seconds"]
batch_size = params["batch_size"]
batch_delay_seconds = params["batch_delay_seconds"]
max_runtime_minutes = params["max_runtime_minutes"]
simulate_failure_rate = params["simulate_failure_rate"]
print("\\n--- 대량 작업 안전 지연 스크립트 시작 ---")
print(f"총 작업 항목: {total_iterations}개")
print(f"항목당 지연: {delay_per_item_seconds:.2f}초")
print(f"배치 크기: {batch_size}개")
print(f"배치당 추가 지연: {batch_delay_seconds:.2f}초")
print(f"최대 실행 시간: {max_runtime_minutes}분")
print(f"시뮬레이션 실패율: {simulate_failure_rate:.2f}")
print("---------------------------------------\\n")
script_start_time = datetime.datetime.now()
max_script_end_time = script_start_time + datetime.timedelta(minutes=max_runtime_minutes)
successful_tasks = 0
failed_tasks = 0
try:
for i in range(total_iterations):
current_item_id = i + 1
current_time = datetime.datetime.now()
# 1. 전체 스크립트 실행 시간 초과 여부 확인
if current_time > max_script_end_time:
print(f"\\n[경고]: 스크립트 최대 실행 시간({max_runtime_minutes}분) 초과. {current_item_id-1}개 작업 후 강제 종료합니다.")
break
print(f"[{current_time.strftime('%Y-%m-%d %H:%M:%S')}] 작업 진행률: {current_item_id}/{total_iterations} ({current_item_id/total_iterations:.1%})")
# 2. 개별 항목 처리 전 지연
if delay_per_item_seconds > 0:
time.sleep(delay_per_item_seconds)
# 3. 작업 시뮬레이션 및 예외 처리
try:
task_success = simulate_task(current_item_id, simulate_failure_rate)
if task_success:
successful_tasks += 1
else:
failed_tasks += 1
except Exception as e:
failed_tasks += 1
print(f" [오류]: 항목 {current_item_id} 처리 중 예상치 못한 오류 발생: {e}")
# 4. 배치 단위 추가 지연
if current_item_id % batch_size == 0 and current_item_id < total_iterations:
print(f"\\n[정보]: {batch_size}개 작업 완료. {batch_delay_seconds:.2f}초 동안 배치 지연...")
time.sleep(batch_delay_seconds)
print("[정보]: 배치 지연 완료.\\n")
except KeyboardInterrupt:
print("\\n[사용자 중단]: 스크립트가 사용자에 의해 중단되었습니다.")
except Exception as e:
print(f"\\n[치명적 오류]: 스크립트 실행 중 예상치 못한 치명적인 오류 발생: {e}")
finally:
end_time = datetime.datetime.now()
elapsed_time = end_time - script_start_time
print("\\n--- 스크립트 실행 요약 ---")
print(f"총 시도 작업: {total_iterations}개")
print(f"성공한 작업: {successful_tasks}개")
print(f"실패한 작업: {failed_tasks}개")
print(f"총 실행 시간: {elapsed_time}")
print("---------------------------\\n")
if __name__ == '__main__':
main()
"""
b64_encoded = base64.b64encode(source_code.encode('utf-8')).decode('utf-8')
print(f"Length of base64: {len(b64_encoded)}")
print(b64_encoded[:100])
```
```text
Length of base64: 10188
aW1wb3J0IHN5cwppbXBvcnQgdGltZQppbXBvcnQgZGF0ZXRpbWUKaW1wb3J0IHJhbmRvbQoKZGVmIHByaW50X3VzYWdlKCk6CiAg
```