Replication between 2 iOS devices and one database use a lot of CPU


#1

Hi everyone !

I’m using couchbase-lite to synchronize data between 2 iOS devices with swift. I set a listener (CBLListener) on my first device and start a pull and push replication between the 2 devices.

As soon as the replication begins, the CPU for the 2 devices increase from 0% to 25-30% and keep 25-30% until the replication is stopped. When I close the app on a device, the CPU usage on the other device decrease to 0%.

It’s a problem for me because when I’m replicating 5 databases, it takes more than 100% of CPU and device is too hot ! Is it a problem with my implementation, swift or is it a problem with the CBLListener / CBL ?

Sorry for my bad english, don’t hesitate to ask me if you need some data.


  • Version: 1.2.1
  • Client OS: iOS 9.3
  • Server: iOS 9.3

#2

There shouldn’t be a lot of CPU usage. You may be doing too much work in notification observers, especially database-changed. Use the time profiler in the Instruments app to see where the CPU time is going.


#3

I have tested without observer this afternoon but it doesn’t work. I will try with a new project with juste replication between the 2 apps because it’s not usable for now :frowning:


#4

EDIT : It’s working with an older version of couchbase lite. I don’t have the version because it’s in my download file since summer 2015. I replace CBListener.framework and CBL.framework and keep my new code… It’s working like a charm. I think it’s a bug with a version between summer 2015 (11 june 2015 for the creation date of the framework file) and 1.2.1… I will try to put to you the version which works.

Do I need to open an issue in GitHub ?

I can send you my project. So it’s working with an older version of CBL and not with 1.2.1 :frowning:

So,

I am just trying with a new project with just a replication between 2 databases with 1 document. When the iPhone replicates a CouchDB in the Cloud, it’s working fine. Document is replicated on my device and CPU stay at 0%.

When I replicate an app on another app with the same code (I just change the URL of the couchDB with an URL local), replication works fine but CPU is using by 30% and stay at 30%. It begins when replication is set (with createPullReplication).

I’m using CBLListener on my 2 apps, without any authentication for now… I don’t understand why replication takes a lot of CPU when I don’t change document.

My code for replication:
pull = self.setupReplication(database.createPullReplication(NSURL(string: replicationURL)!))

and setUpReplication:
> func setupReplication(replication: CBLReplication!) -> CBLReplication! {

        if replication != nil {
            replication.continuous = true
            NSNotificationCenter.defaultCenter().addObserver(self,
                                                             selector: #selector(replicationProgress(_:)),
                                                             name: kCBLReplicationChangeNotification,
                                                             object: replication)
        }
        return replication
    }

#5

Once again: Please use the Instruments app to see where the CPU time is being spent.


#6

You can find paste of screen capture of instrument here : http://imgur.com/a/EvvR3

It shows the 4 threads which take a lot of CPU.

It does not really help me.


#7

All this shows is that 29% of the running time was spent in a background thread. You’d need to open up that outline item to find the stack frames in that thread that are using time.

I’m sorry, but I don’t have the time to explain how to use Instruments. Apple has documentation on that. If you can narrow down the problem to something in Couchbase Lite itself, we can take a look. But in other cases like this one, the CPU usage has come from application code that’s being triggered by database changes and doing an excessive amount of work in response.


#8

Edit : To help you, I have tested with framework 1.1.1 available for download and it works. I have tester with 1.2 and 1.2.1 and it does not work. CPU increase with 1.2 and 1.2.1. It’s a change in the framework or the listener between 1.1 and 1.2

I understand your position and it’s why I’m trying to help you with information for helping me.

I think it’s not in my code because I do nothing in my code. It’s just a new project swift with a couchbaselite database - without any document ! (write with the sample code provided on couchbase lite website) and a replication between an app with this database. There is no extra code. When I launch the second app replication, CPU increase directly. When I used an older version of framework, it’s work like a charm.

I will try to help you with more explainations / instrument details. I don’t know why I pasted this screen which show nothing. My bad.

So, with instrument:
In my app, I have no network call except replication between the 2 databases and I see that the thread which takes a lot of CPU is _tcp_connection_start_block_invoke. There is a lot of thread links to TCP_Connection and SocketStream. I don’t find a clue of CouchBase but I have no network call in my app except replication.

It’s like pull replication between 2 couchbase lite do something that replication with cloud do not, and works with an older version of couchbase lite. It’s really strange… Like an infinite loop when replication is launched.


#9

Upload your project somewhere and I can take a look at it.

There is a lot of thread links to TCP_Connection and SocketStream.

That’s not Couchbase code; sounds like the internals of Apple’s networking frameworks.


#10

Hi ! Thank you for the proposition !

My project is available with this link : removed

Please, let me know when you have downloaded the project, I would like to destroy the sharing after your download.

You have just to build on 2 iOS devices or 1 device and 1 simulator. This version of my code launch the replication with MultipeerConnection framework (Apple framework) but you can disable it and just start the replication with URL hard-coded like http://172.16.1.12:8080/product for example.

This version uses CouchBase Lite 1.2.1 with the problem of CPU. If you change the 2 framework CBListener and Couchbase Lite, you will see that there is no problem. Obviously, I would prefer use 1.2.1.

Thank you in advance, I hope you will be find something.


#11

The project you sent me has extra code, Swift classes like PeersConnectionManager, CouchDBDriver, ReplicationManager, etc. I thought you were just running one of our sample apps.

I’m sorry, but I don’t have time to debug this for you. (I’m not in tech support, I’m a developer.) I suggest turning on logging to see what the replicator is doing, adding some of your own logging to see how many replications you’re creating and how often your notifications get called, and of course using Instruments to profile.