Repository: wandb/wandb

Issue:
[CLI]: wandb.errors.UsageError: Timeout attaching to run when in offline mode
### Describe the bug

<!--- Description of the issue below  -->
When I try to access the config of the run object, I get the exception below. However, this only happens when in offline mode; it works fine when in online mode. (note that I am using multiprocessing as shown below and cannot seem to reproduce in the simple two-line code of a single process run=wandb.init; config=run.config). It only works when in online mode, and I can repro 100% when in offline mode.

<!--- A minimal code snippet between the quotes below  -->
```python
import multiprocessing
import wandb

def simple_bug_f(wandb_run):
    print("Trying to get config")
    config = wandb_run.config
    print("Got config")

if __name__ == '__main__':
    wandb_run = wandb.init(mode="offline")
    
    ctx = multiprocessing.get_context('spawn')
    pool = ctx.Pool(processes=2)

    futures = []
    for i in range(2):
        future = pool.apply_async(simple_bug_f, args=(wandb_run,))
        futures.append(future)
    
    [future.get() for future in futures]

```

<!--- A full traceback of the exception in the quotes below -->
```shell
    config = wandb_run.config
  File "python3.8/site-packages/wandb/sdk/wandb_run.py", line 332, in wrapper
    raise e
  File "python3.8/site-packages/wandb/sdk/wandb_run.py", line 327, in wrapper
    wandb._attach(run=self)
  File "python3.8/site-packages/wandb/sdk/wandb_init.py", line 897, in _attach
    raise UsageError("Timeout attaching to run")
wandb.errors.UsageError: Timeout attaching to run
```


### Additional Files

_No response_

### Environment

WandB version: 0.13.10

OS: Linux

Python version: 3.8

Versions of relevant libraries:

**Also tried in another totally different environment which has python 3.9.10** I see the problem exactly the same

### Additional Context

_No response_


Discussion:
Did some digging and I can see that _attach in wandb_init.py does not have any offline handling code and always assumes online. As per a TODO comment, this code needs to be consolidated with the wandb.init() path which has handling for offline mode. 
@RamyE Thanks for reporting this issue! I will take a look at this, but your observation seems to be correct.
Hey @kptkin,
Can I pick this up ? 
Hey @techytushar sure you can! Thank you very much for proposing your help!
Bill Morrisson commented: 
Hello @techytushar, have you been able to take a look at it?

@billmdevs I didn't get a chance to look into this, will be working on this over the weekend 

Resolving patch:
diff --git a/wandb/sdk/wandb_init.py b/wandb/sdk/wandb_init.py
--- a/wandb/sdk/wandb_init.py
+++ b/wandb/sdk/wandb_init.py
@@ -871,11 +871,7 @@ def _attach(
 
     settings: Settings = copy.copy(_wl._settings)
     settings.update(
-        {
-            "run_id": attach_id,
-            "_start_time": response["_start_time"],
-            "_start_datetime": response["_start_datetime"],
-        },
+        {"run_id": attach_id, **response},
         source=Source.INIT,
     )
 
@@ -895,6 +891,10 @@ def _attach(
     assert backend.interface
 
     mailbox.enable_keepalive()
+
+    if run.settings._offline:
+        return run
+
     attach_handle = backend.interface.deliver_attach(attach_id)
     # TODO: add progress to let user know we are doing something
     attach_result = attach_handle.wait(timeout=30)


Test patch:
diff --git a/tests/functional_tests/t0_main/offline/t2_multiprocess.py b/tests/functional_tests/t0_main/offline/t2_multiprocess.py
new file mode 100644
--- /dev/null
+++ b/tests/functional_tests/t0_main/offline/t2_multiprocess.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+"""Offline runs running in different processes.
+
+---
+id: 0.offline.02-multiprocess
+env:
+  - WANDB_BASE_URL: https://does.not-resolve/
+command:
+  timeout: 20
+plugin:
+  - wandb
+assert:
+  - :wandb:runs_len: 1
+  - :wandb:runs[0][config]: {}
+  - :wandb:runs[0][summary]:
+      metric: 10
+  - :wandb:runs[0][exitcode]: 0
+  - :yea:exit: 0
+"""
+
+import multiprocessing
+
+import wandb
+
+
+def log_metric(wandb_run):
+    wandb_run.log({"metric": 10})
+
+
+if __name__ == "__main__":
+    wandb_run = wandb.init(mode="offline")
+
+    ctx = multiprocessing.get_context("spawn")
+    pool = ctx.Pool(processes=2)
+
+    futures = []
+    for _ in range(2):
+        future = pool.apply_async(log_metric, args=(wandb_run,))
+        futures.append(future)
+
+    [future.get() for future in futures]