Torom / BotLi

Lichess Bot
GNU Affero General Public License v3.0
46 stars 82 forks source link

Dockerized version RuntimeError #150

Closed Intron014 closed 12 months ago

Intron014 commented 12 months ago

Please read, understand and follow: https://lichess.org/@/thibault/blog/how-to-ask-technical-questions/1HSthDSX

Describe the bug When run in a dockerized version Dockerfile:

FROM python:latest
COPY . .
RUN pip --no-cache-dir install -U pip && pip --no-cache-dir install -r requirements.txt
CMD ["python3", "user_interface.py", "-m"]

it starts like this:

______       _   _     _ 
| ___ \     | | | |   (_)
| |_/ / ___ | |_| |    _ 
| ___ \/ _ \| __| |   | |
| |_/ / (_) | |_| |___| |
\____/ \___/ \__\_____/_| 20230913-c477087
Testing engine "standard" ... OK
Handling challenges ...
Starting matchmaking ...
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/lib/python3.12/threading.py", line 1052, in _bootstrap_inner
    self.run()
  File "/game_manager.py", line 53, in run
    self._start_game(self.started_game_ids.popleft())
  File "/game_manager.py", line 133, in _start_game
    self.games[game_id].start()
  File "/game.py", line 24, in start
    Thread.start(self)
  File "/usr/local/lib/python3.12/threading.py", line 971, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't create new thread at interpreter shutdown

To Reproduce This is the file structure of the docker volume (what I copy).

├── aliases.py ├── api.py ├── botli_dataclasses.py ├── botli.log ├── challenger.py ├── challenge_validator.py ├── chatter.py ├── config.py ├── config.yml ├── Dockerfile ├── engine.py ├── engines │   ├── brainlearn │   ├── Brainlearn26.2-x86-64-bmi2 │   ├── DarkMatter.bin │   ├── experience.exp ├── enums.py ├── event_handler.py ├── game_manager.py ├── game.py ├── Intron014_matchmaking.json ├── LICENSE ├── lichess_game.py ├── logo.py ├── matchmaking.py ├── opponents.py ├── pending_challenge.py ├── pycache │   ├── aliases.cpython-310.pyc │   ├── aliases.cpython-311.pyc │   ├── api.cpython-310.pyc │   ├── api.cpython-311.pyc │   ├── botli_dataclasses.cpython-310.pyc │   ├── botli_dataclasses.cpython-311.pyc │   ├── challenger.cpython-310.pyc │   ├── challenger.cpython-311.pyc │   ├── challenge_validator.cpython-310.pyc │   ├── challenge_validator.cpython-311.pyc │   ├── chatter.cpython-310.pyc │   ├── chatter.cpython-311.pyc │   ├── config.cpython-310.pyc │   ├── config.cpython-311.pyc │   ├── engine.cpython-310.pyc │   ├── engine.cpython-311.pyc │   ├── enums.cpython-310.pyc │   ├── enums.cpython-311.pyc │   ├── event_handler.cpython-310.pyc │   ├── event_handler.cpython-311.pyc │   ├── game.cpython-310.pyc │   ├── game.cpython-311.pyc │   ├── game_manager.cpython-310.pyc │   ├── game_manager.cpython-311.pyc │   ├── lichess_game.cpython-310.pyc │   ├── lichess_game.cpython-311.pyc │   ├── logo.cpython-310.pyc │   ├── logo.cpython-311.pyc │   ├── matchmaking.cpython-310.pyc │   ├── matchmaking.cpython-311.pyc │   ├── opponents.cpython-310.pyc │   ├── opponents.cpython-311.pyc │   ├── pending_challenge.cpython-310.pyc │   └── pending_challenge.cpython-311.pyc ├── README.md ├── requirements.txt └── user_interface.py

Expected behavior It starts matchmaking

Information:

Config:

engines:
  standard:                               # Engine used for standard chess and when no suitable special engine is configured.
    dir: "./engines"                      # Directory containing the engine.
    #name: "Brainlearn26.2-x86-64-bmi2"                     # Binary name of the engine to use.
    name: "brainlearn"                     # Binary name of the engine to use.
    ponder: true                          # Think on opponent's time.
    use_syzygy: true                      # Whether the engine should be configured to use syzygy.
    silence_stderr: true                  # Suppresses stderr output.
    uci_options:                          # Arbitrary UCI options passed to the engine. (Commenting allowed)
      Threads: 2                          # Max CPU threads the engine can use.
      Hash: 512                           # Max memory (in megabytes) the engine can allocate.
      Move Overhead: 650                  # Increase if your bot flags games too often.
      SyzygyPath: "./engines/syzygy"
      SyzygyProbeLimit: 5

syzygy:
  enabled: true                           # Activate local syzygy endgame tablebases.
  paths:                                  # Paths to local syzygy endgame tablebases.
    - "./engines/syzygy"
  max_pieces: 5                           # Count of max pieces in the local syzygy endgame tablebases.
  instant_play: true                      # Whether the bot should play directly from syzygy without engine if possible.

gaviota:
  enabled: false                          # Activate local gaviota endgame tablebases.
  paths:                                  # Paths to local gaviota endgame tablebases.
    - "/path/to/gaviota"
  max_pieces: 5                           # Count of max pieces in the local gaviota endgame tablebases.

opening_books:
  enabled: true                           # Activate opening books.
  priority: 400                           # Priority with which this move source is used. Higher priority is used first.
  books:
#   bullet:
#     selection: weighted_random          # Move selection is one of "weighted_random", "uniform_random" or "best_move".
#     names:                              # List of names of books to use in bullet.
#       - BulletBook
#       - DefaultBook
    standard_white:
      selection: weighted_random          # Move selection is one of "weighted_random", "uniform_random" or "best_move".
      names:
        - "DarkMatter"
    standard_black:
      selection: best_move               # Move selection is one of "weighted_random", "uniform_random" or "best_move".
      names:
        - "DarkMatter"

online_moves:
  opening_explorer:
    enabled: false                        # Activate online moves from Lichess opening explorer. The move that has performed best for this bot is played.
    priority: 300                         # Priority with which this move source is used. Higher priority is used first.
    use_for_variants: false               # Whether the Lichess opening explorer should be used for other variants than standard and chess960.
    min_time: 20                          # Time the bot must have at least to use the online move.
    timeout: 5                            # Time the server has to respond.
    min_games: 5                          # Minimum number of games in which the position must have occurred.
    only_with_wins: false                 # Whether to play only moves that have won before.
    selection: "performance"              # Move selection is "performance" or "win_rate".
    anti: false                           # Whether to play the moves in which the opponent performs the worst.
#   max_depth: 16                         # Half move max depth. (Comment this line for max depth)
#   max_moves: 1                          # Max number of moves played from Lichess opening explorer. (Comment this line for max moves)
  lichess_cloud:
    enabled: false                        # Activate online moves from Lichess cloud eval.
    priority: 200                         # Priority with which this move source is used. Higher priority is used first.
    only_without_book: false              # Whether the cloud should only be used if there is no matching book.
    min_eval_depth: 10                    # Minimum evaluation depth.
    min_time: 20                          # Time the bot must have at least to use the online move.
    timeout: 5                            # Time the server has to respond.
#   max_depth: 16                         # Half move max depth. (Comment this line for max depth)
#   max_moves: 1                          # Max number of moves played from Lichess cloud eval. (Comment this line for max moves)
  chessdb:
    enabled: false                        # Activate online moves from https://chessdb.cn/queryc_en/
    priority: 100                         # Priority with which this move source is used. Higher priority is used first.
    min_eval_depth: 10                    # Minimum evaluation depth.
    min_time: 20                          # Time the bot must have at least to use the online move.
    timeout: 5                            # Time the server has to respond.
#   max_depth: 16                         # Half move max depth. (Comment this line for max depth)
#   max_moves: 1                          # Max number of moves played from chessdb. (Comment this line for max moves)
  online_egtb:
    enabled: true                         # Activate online endgame tablebases from Lichess.
    min_time: 10                          # Time the bot must have at least to use the online move.
    timeout: 2                            # Time the server has to respond.

offer_draw:
  enabled: true                           # Activate whether the bot should offer draw.
  score: 10                               # If the absolute value of the score is less than or equal to this value, the bot offers/accepts draw (in cp)
  consecutive_moves: 10                   # How many moves in a row the absolute value of the score has to be below the draw value
  min_game_length: 35                     # Earliest move in which draw is offered.

resign:
  enabled: false                          # Activate whether the bot should resign games.
  score: -1000                            # If the score is less than or equal to this value, the bot resigns (in cp).
  consecutive_moves: 5                    # How many moves in a row the score has to be below the resign value.

move_overhead_multiplier: 1.1             # Increase if your bot flags games too often. Default move overhead is 1 second per 1 minute initital time.

challenge:                                # Incoming challenges. (Commenting allowed)
  concurrency: 1                          # Number of games to play simultaneously.
  bullet_with_increment_only: true        # Whether bullet games against BOTs should only be accepted with increment.
# min_increment: 1                        # Minimum amount of increment to accept a challenge.
  max_increment: 5                        # Maximum amount of increment to accept a challenge.
  min_initial: 60                         # Minimum amount of initial time to accept a challenge.
  max_initial: 1800                       # Maximum amount of initial time to accept a challenge.
  variants:                               # Chess variants to accept (https://lichess.org/variant).
    - standard
    - chess960
#   - fromPosition
#   - antichess
#   - atomic
#   - crazyhouse
#   - horde
#   - kingOfTheHill
#   - racingKings
#   - threeCheck
  time_controls:                          # Speeds or time controls in initial_minutes+increment_seconds format to accept.
    - bullet
    - blitz
    - rapid
#   - classical
  bot_modes:                              # Game modes to accept against BOTs.
#   - casual                              # Unrated games.
    - rated                               # Rated games
  human_modes:                            # Game modes to accept against humans.
#   - casual                              # Unrated games.
#   - rated                               # Rated games

matchmaking:
  delay: 150                              # Time in seconds the bot must be idle before a new challenge is started.
  timeout: 30                             # Time until a challenge is canceled.
  types:                                  # Matchmaking types of which one is randomly selected before each game.
    bullet:                               # Arbitrary name of the matchmaking type. Names must be unique.
      tc: 1+1                             # Time control in initial_minutes+increment_seconds format.
      rated: true                         # Whether matchmaking should play rated games.
      variant: standard                   # Chess variant (https://lichess.org/variant) to challenge.
      weight: 35                          # Weight with which this type is selected. (Default: 100)
      multiplier: 20                      # Multiplier for calculating timeouts in matchmaking. Higher values lead to a wider range of opponents
    blitz:                                # Arbitrary name of the matchmaking type. Names must be unique.
      tc: 3+0                             # Time control in initial_minutes+increment_seconds format.
      rated: true                         # Whether matchmaking should play rated games.
      variant: standard                   # Chess variant (https://lichess.org/variant) to challenge.
      weight: 35                          # Weight with which this type is selected. (Default: 100)
      multiplier: 20                      # Multiplier for calculating timeouts in matchmaking. Higher values lead to a wider range of opponents.
    rapid:                                # Arbitrary name of the matchmaking type. Names must be unique.
      tc: 8+0                             # Time control in initial_minutes+increment_seconds format.
      rated: true                         # Whether matchmaking should play rated games.
      variant: standard                   # Chess variant (https://lichess.org/variant) to challenge.
      weight: 15                          # Weight with which this type is selected. (Default: 100)
      multiplier: 20                      # Multiplier for calculating timeouts in matchmaking. Higher values lead to a wider range of opponents.
    classical:                            # Arbitrary name of the matchmaking type. Names must be unique.
      tc: 25+0                            # Time control in initial_minutes+increment_seconds format.
      rated: true                         # Whether matchmaking should play rated games.
      variant: standard                   # Chess variant (https://lichess.org/variant) to challenge.
      weight: 15                          # Weight with which this type is selected. (Default: 100)
      multiplier: 20                      # Multiplier for calculating timeouts in matchmaking. Higher values lead to a wider range of opponents.

messages:
  # Optional substitution keywords (include curly braces):
  #   {opponent} to insert the opponent's name
  #   {me} to insert our name
  #   {engine} to insert engine name
  #   {cpu} to insert CPU information
  #   {ram} to insert RAM size
  # Any other words in curly braces will be removed.
  greeting: "Hey, I'm {me}, let's go!" # Message sent to the opponent at the beginning of a game.
  goodbye: "Good game {opponent} , cya."                                             # Message sent to the opponent after the end of a game.
  greeting_spectators: "" # Message sent to the spectators at the beginning of a game.
  goodbye_spectators: ""                                           # Message sent to the spectators after the end of a game.

# whitelist:                              # List of users whose challenges are always accepted.
#   - Username1
#   - Username2

blacklist:                              # List of users who are not challenged and whose challenges are declined.
    - ElmiChess

books:                                    # Names of the opening books (to be used above in the opening_books section) and paths to the opening books.
 DarkMatter: "./engines/DarkMatter.bin"

Additional context :D

Torom commented 12 months ago

Your BotLi version 20230913-c477087 is two month old. The problem was fixed with b08363d a month ago.

Intron014 commented 12 months ago

Damn, thanks! Sorry to bother again but now I have not output in the logs :( The bot works! The output of the script is just not appearing

Torom commented 12 months ago

This could happen due to output buffer. Start Python with -u to deactivate the output buffer.

CMD ["python3", "-u", "user_interface.py", "-m"]

Intron014 commented 12 months ago

Perfect! Thanks a lot! :D