textileio / ios-textile

[DEPRECATED] iOS bindings for https://github.com/textileio/go-textile
MIT License
10 stars 6 forks source link

Destroy method issue #77

Open Batvos opened 5 years ago

Batvos commented 5 years ago

Hi, I’ve implemented logout but it seems that it works not as I expected.

My logout implementation contains 2 steps: call destroy methods and remove repo. So far so good. But if I try to login again with the repo path that I used for previous account I get error. It’ll work only either I’ll restart app or change repo path.

Also I've noticed that I should wait for a while after call destroy method. Could you add async callback to destroy methods for waiting while it's finishing all cleaning tasks?

Here's error I got _TextileExample[9005:672457] A background URLSession with identifier textile already exists! _TextileExample[9005:672457] launch error: unable to open database file

I use latest version of ios-textile 2.0.8

asutula commented 5 years ago

Could you try your logout method using the newly released ios-textile 2.0.9? I made a little change in there that could work around the error you were getting. Thanks.

Batvos commented 5 years ago

@asutula Hi, I've gotten the same result when call initialize:seed:debug:logToDisk:error: after calling destroy methods and remove repo.

Error Domain=go Code=1 "could not build arguments for function "reflect".makeFuncStub (/Users/distiller/gosrc/go/src/reflect/asm_amd64.s:12): failed to build *mfs.Root: function "github.com/ipfs/go-ipfs/core/node".Files (/Users/distiller/go/src/github.com/textileio/go-textile/vendor/github.com/ipfs/go-ipfs/core/node/core.go:77) returned a non-nil error: failure writing to dagstore: mkdir /Users/batvos/Library/Developer/CoreSimulator/Devices/25DABC67-50BA-4336-8931-5014D8C4E8A1/data/Containers/Data/Application/7A6BF51C-8AAF-4189-B550-250BB93B8E7D/Documents/textile-go/blocks/X3: no such file or directory" UserInfo={NSLocalizedDescription=could not build arguments for function "reflect".makeFuncStub (/Users/distiller/gosrc/go/src/reflect/asm_amd64.s:12): failed to build *mfs.Root: function "github.com/ipfs/go-ipfs/core/node".Files (/Users/distiller/go/src/github.com/textileio/go-textile/vendor/github.com/ipfs/go-ipfs/core/node/core.go:77) returned a non-nil error: failure writing to dagstore: mkdir /Users/batvos/Library/Developer/CoreSimulator/Devices/25DABC67-50BA-4336-8931-5014D8C4E8A1/data/Containers/Data/Application/7A6BF51C-8AAF-4189-B550-250BB93B8E7D/Documents/textile-go/blocks/X3: no such file or directory} (lldb)

Batvos commented 5 years ago

Could you rewrite destroy method like this?

- (void)destroy:(void (^)(BOOL, NSError * _Nullable))completion {
  [self stopWithCompletion:^(BOOL success, NSError * _Nullable error) {
    self.delegate = nil;
    self.node = nil;
    self.messenger = nil;
    self.lifecycleManager = nil;
    self.requestsHandler = nil;

    self.account = nil;
    self.cafes = nil;
    self.comments = nil;
    self.contacts = nil;
    self.feed = nil;
    self.files = nil;
    self.flags = nil;
    self.ignores = nil;
    self.invites = nil;
    self.ipfs = nil;
    self.likes = nil;
    self.logs = nil;
    self.messages = nil;
    self.notifications = nil;
    self.profile = nil;
    self.schemas = nil;
    self.threads = nil;

      completion(success, error);
  }];
}
asutula commented 5 years ago

Yes, i'll have an update out in a few minites

asutula commented 5 years ago

PR here https://github.com/textileio/ios-textile/pull/83

asutula commented 5 years ago

Ok 2.0.10 is out:

- (void)destroyWithCompletion:(nullable void (^)(BOOL success, NSError * _Nullable error))completion;

Let me know how that works for you.

Batvos commented 5 years ago

@asutula I got the same error as here https://github.com/textileio/ios-textile/issues/77#issuecomment-529105675 trying login after logout.

Here is a log of this error from console

2019-09-10 01:25:24.860322 DEBUG dht query.go:253: error connecting: failed to dial : all dials failed
  * [/ip4/127.0.0.1/tcp/4001] dial tcp4 127.0.0.1:4001: connect: connection refused
  * [/ip6/::1/tcp/4001] dial tcp6 [::1]:4001: connect: connection refused
  * [/ip4/192.99.58.74/tcp/4001] dial tcp4 192.99.58.74:4001: i/o timeout
2019-09-10 01:25:24.860337 DEBUG addrutil addr.go:121: InterfaceAddresses: from manet: [/ip4/127.0.0.1 /ip6/::1 /ip6/fe80::1 /ip6/fe80::c02:84d2:55aa:e393 /ip4/192.168.0.3 /ip6/fe80::9416:60ff:fed3:265e /ip6/fe80::821e:f15b:22a3:3e92 /ip6/fe80::8be0:eec5:5d89:cc7c /ip6/fe80::955d:48fc:7b59:23d8 /ip6/fe80::ca87:916d:28fe:c34]
2019-09-10 01:25:24.860338 DEBUG dht dial_queue.go:328: discarding dialled peer because of error: failed to dial : all dials failed
  * [/ip4/127.0.0.1/tcp/10001] dial tcp4 127.0.0.1:10001: connect: connection refused
  * [/ip6/::1/tcp/10001] dial tcp6 [::1]:10001: connect: connection refused
  * [/ip4/113.89.191.67/tcp/22748] dial tcp4 113.89.191.67:22748: i/o timeout
  * [/ip4/192.168.16.149/tcp/10001] dial tcp4 192.168.16.149:10001: i/o timeout
2019-09-10 01:25:24.860323 DEBUG swarm2 limiter.go:109: [limiter] freeing peer token; peer QmNhcbmWg8F2SZ5ooa3SswaV3CqnkHYpZQF3i1mPQ61idj; addr: /ip4/104.238.222.133/tcp/4001/ipfs/QmUZjttfuPiyoPH8c8KpCk9xrMsqLcZX6mzBc9EM7uiz16/p2p-circuit; active for peer: 3; waiting on peer limit: 0

I've noticed that on the repo path have been created some files successfully: config, datastore_spec, repover, textile, version. I can share them with you if you need.

And two more bugs: Despite that initialization failed to start + (id)isInitialized:(id)repoPath method returns YES and If I try call destroy method completion will never get called till I remove that repo.

asutula commented 5 years ago

Can you send me your logout code? I'd like to try to run it here.

Batvos commented 5 years ago

It's pretty simple. I can create a test project with logout if you need?

if Textile.isInitialized(textileRepo) {
    Textile.instance().destroy { isSuccess, error in
        try? FileManager.default.removeItem(atPath: self.textileRepo)

        DispatchQueue.main.async {
            completion()
        }
    }
}
asutula commented 5 years ago

I re-created your logout setup here already and can see the same errors you report. I'm suspicious that the core go-textile library that ios-textile wraps is hanging onto some state from the previous repo instance that is causing this error when you try to re-initialize.

@sanderpick, for some quick context, @Batvos is trying to implement log out and log back in again. Here is the flow that is leading to the error we're seeing:

  1. From a new/fresh install, initialize textile
  2. textile is started and online
  3. stop texilte
  4. call an sdk-specific destroy method that cleans up and resets some sdk state
  5. delete the textiel repo directory
  6. re-initialize textile with the same repo directory
  7. get the following error when calling initialize:

failure writing to dagstore: mkdir /Users/aaron/Library/Developer/CoreSimulator/Devices/CA2C4C13-D1EA-47AB-8A5E-F9405307A9C6/data/Containers/Data/Application/C201ACFE-0DA6-4564-A755-7F0A71311555/Documents/textile-go/blocks/X3: no such file or directory

Any ideas?

sanderpick commented 5 years ago

@asutula are you recreating the underlying Textile instance? It holds a reference to the repo.

asutula commented 5 years ago

Yea I suppose so. That is the point, I guess, of logging out and logging back in with a different account. As I've mentioned earlier in this issue, we haven't really explicitly designed and built the "log out" use case, so this may be a case of abusing the current APIs.

asutula commented 5 years ago

To clarify @sanderpick, I think we are recreating the underlying Textile instance because we are calling MobileInitRepo (which tries to create the repo) and MobileNewTextile (which creates the node instance) again. Actually, in this case, we never get to MobileNewTextile because it's the call to MobileInitRepo that fails.

sanderpick commented 5 years ago

Hrm, if the repo is really deleted and the go-textile Textile instance is truly disposed, I'm not sure how this is possible. Or in other words, if you kill all the state, there can't be any state left to cause problems, right?

asutula commented 5 years ago

Makes sense. I'm wondering if there is some state internal to go-textile that could still be hanging around? Or is all state contained in the textile node object that I am trying to dispose of?

asutula commented 5 years ago

Also, the error I'm seeing is coming from MobileInitRepo which shouldn't have much, if anything, to do with the node instance (because it runs before the node instance even exists under normal circumstances).

asutula commented 5 years ago

Oh, I didn't paste the whole error above. Here's the whole thing. It's actually pretty specific about where things are going wrong:

could not build arguments for function "reflect".makeFuncStub (/Users/distiller/gosrc/go/src/reflect/asm_amd64.s:12): failed to build *mfs.Root: function "github.com/ipfs/go-ipfs/core/node".Files (/Users/distiller/go/src/github.com/textileio/go-textile/vendor/github.com/ipfs/go-ipfs/core/node/core.go:77) returned a non-nil error: failure writing to dagstore: mkdir /Users/aaron/Library/Developer/CoreSimulator/Devices/CA2C4C13-D1EA-47AB-8A5E-F9405307A9C6/data/Containers/Data/Application/C201ACFE-0DA6-4564-A755-7F0A71311555/Documents/textile-go/blocks/X3: no such file or directory
sanderpick commented 5 years ago

Right, there's no external state to the node. Seems your instance is trying to access an old file that is since deleted.

asutula commented 5 years ago

Would calling MobileInitRepo when there is still an instance of the node in existence try to re-use the existing instance? In the ios-textile layer, I'm doing everything I can to allow the old instance of the node to be deallocated, but I wonder if code in the go layer is hanging onto the previous instance?

asutula commented 5 years ago

Oh, I guess the node instance returned from MobileNewTextile is the top level object that contains all state?

Suspiciously reading https://godoc.org/golang.org/x/mobile/cmd/gobind#hdr-Avoid_reference_cycles

asutula commented 5 years ago

@sanderpick I'm doing some more tests around this problem and it's pointing to some state in go-textile or go-ipfs causing the problem. What I'm seeing is that if I destroy all the sdk state, delete the repo dir, and re-initialize the repo in the same location, I get the errors we've been talking about. If I change the location of the repo the second time the repo is initialized, things work fine.

@Batvos you could use that behavior as a workaround for now possibly.

Batvos commented 5 years ago

@asutula Thanks. For now I use this workaround. Any chance that you fix this soon?

asutula commented 5 years ago

I hope I can fix it soon. Still investigating what the problem could be. I'll keep you posted here.

Batvos commented 5 years ago

Hi, Is there any progress with issue?

asutula commented 4 years ago

Hey sorry for the delay on replying. I don't have any update for you right now. I started digging into this more, but got sidetracked with work on our new version of Textile Threads. This issue will still be relevant in the new version too, so I do want to keep going on this. I'll get back to it asap.

asutula commented 4 years ago

Actually, let me give a little detail about were I left my investigation into this...

I'm suspicious that there is a retain cycle happening between our native sdk code and cross platform library that is written in Go and embedded into the SDK. This retain cycle may be maintaining some state/object instance and that old instance may cause things go wrong when you try to re-create the repo.

Later today, I'll write a test in our Go project (go-textile) to verify that this logout/login flow works when the native sdk code isn't involved. If that is the case, I'll then reach out to get some help figuring out this retain cycle stuff.