Create non-thread-safe RWLock for file paths. Args: tmp_dir (str): existing directory where to create the rwlock file. fs (FileSystem): fs instance that tmp_dir belongs to. cmd (str): command that will be working on these file path. read ([str]): file paths that
(tmp_dir, fs, cmd, read, write, hardlink)
| 186 | |
| 187 | @contextmanager |
| 188 | def rwlock(tmp_dir, fs, cmd, read, write, hardlink): |
| 189 | """Create non-thread-safe RWLock for file paths. |
| 190 | |
| 191 | Args: |
| 192 | tmp_dir (str): existing directory where to create the rwlock file. |
| 193 | fs (FileSystem): fs instance that tmp_dir belongs to. |
| 194 | cmd (str): command that will be working on these file path. |
| 195 | read ([str]): file paths that are going to be read. |
| 196 | write ([str]): file paths that are going to be written. |
| 197 | hardlink (bool): use hardlink lock to guard rwlock file when on edit. |
| 198 | |
| 199 | Raises: |
| 200 | LockError: raised if file paths we want to read is being written to by |
| 201 | another command or if file paths we want to write is being written |
| 202 | to or read from by another command. |
| 203 | RWLockFileCorruptedError: raised if rwlock file is not a valid JSON. |
| 204 | RWLockFileFormatError: raised if rwlock file is a valid JSON, but |
| 205 | has internal format that doesn't pass our schema validation. |
| 206 | """ |
| 207 | info = {"pid": os.getpid(), "cmd": cmd} |
| 208 | |
| 209 | with _edit_rwlock(tmp_dir, fs, hardlink) as lock: |
| 210 | _check_blockers(tmp_dir, lock, info, mode="write", waiters=read + write) |
| 211 | _check_blockers(tmp_dir, lock, info, mode="read", waiters=write) |
| 212 | |
| 213 | rchanges = _acquire_read(lock, info, read) |
| 214 | wchanges = _acquire_write(lock, info, write) |
| 215 | |
| 216 | try: |
| 217 | yield |
| 218 | finally: |
| 219 | with _edit_rwlock(tmp_dir, fs, hardlink) as lock: |
| 220 | _release_write(lock, info, wchanges) |
| 221 | _release_read(lock, info, rchanges) |