class_docstr: Redis storage class for Journal log backend.
  
  Args:
      url:
          URL of the redis storage, password and db are optional.
          (ie: ``redis://localhost:6379``)
      use_cluster:
          Flag whether you use the Redis cluster. If this is :obj:`False`, it is assumed that
          you use the standalone Redis server and ensured that a write operation is atomic. This
          provides the consistency of the preserved logs. If this is :obj:`True`, it is assumed
          that you use the Redis cluster and not ensured that a write operation is atomic. This
          means the preserved logs can be inconsistent due to network errors, and may
          cause errors.
      prefix:
          Prefix of the preserved key of logs. This is useful when multiple users work on one
          Redis server.
class_docstr_tok: ["Redis","storage","class","for","Journal","log","backend",".","Args",":","url",":","URL","of","the","redis","storage",",","password","and","db","are","optional",".","(","ie",":","``","redis",":","\/\/localhost:6379","``",")","use_cluster",":","Flag","whether","you","use","the","Redis","cluster",".","If","this","is",":","obj",":","`","False","`",",","it","is","assumed","that","you","use","the","standalone","Redis","server","and","ensured","that","a","write","operation","is","atomic",".","This","provides","the","consistency","of","the","preserved","logs",".","If","this","is",":","obj",":","`","True","`",",","it","is","assumed","that","you","use","the","Redis","cluster","and","not","ensured","that","a","write","operation","is","atomic",".","This","means","the","preserved","logs","can","be","inconsistent","due","to","network","errors",",","and","may","cause","errors",".","prefix",":","Prefix","of","the","preserved","key","of","logs",".","This","is","useful","when","multiple","users","work","on","one","Redis","server","."]
code: def read_logs(self, log_number_from: int) -> List[Dict[str, Any]]:
      max_log_number_bytes = self._redis.get(
          f"{self._prefix}:log_number"
      )
      if max_log_number_bytes is None:
          return []
      max_log_number = int(max_log_number_bytes)
  
      logs = []
      for log_number in range(log_number_from, max_log_number + 1):
          sleep_secs = 0.1
          while True:
              log = self._redis.get(self._key_log_id(log_number))
              if log is not None:
                  break
              time.sleep(sleep_secs)
              sleep_secs = min(sleep_secs * 2, 10)
          try:
              logs.append(json.loads(log))
          except json.JSONDecodeError as err:
              if log_number != max_log_number:
                  raise err
      return logs
  
imports: import json
  import time
  from typing import Any
  from typing import Dict
  from typing import List
  from typing import Optional
  from optuna._experimental import experimental_class
  from optuna._imports import try_import
  from optuna.storages._journal.base import BaseJournalLogSnapshot
  from optuna.storages._journal.base import BaseJournalLogStorage
label_desc: Use image node_id 4 for calling the JournalRedisStorage obj's underlying member method code with example usage: obj.read_logs(log_number_from) and returns: logs, list