Foren

Deadlock with CacheFirst

thumbnail
Salva Tejero, geändert vor 7 Jahren.

Deadlock with CacheFirst

Junior Member Beiträge: 77 Beitrittsdatum: 13.06.11 Neueste Beiträge
Hello,

I have a AssetListScreenlet
FirstViewController: BaseViewController, AssetListScreenletDelegate {
    
    @IBOutlet var screenlet: AssetListScreenlet?
...
        self.screenlet?.offlinePolicy = CacheStrategyType.CacheFirst.rawValue
        self.screenlet?.delegate = self
        self.screenlet?.groupId = 42954
        self.screenlet?.classNameId = 20109
        let customQuery:[String: AnyObject] = ["classTypeIds": [42983]]
        self.screenlet?.customEntryQuery = customQuery
...

}


If I change CacheStrategyType to RemoteFirst all is ok

Error in "YapDatabaseConnection.m"


#ifndef NS_BLOCK_ASSERTIONS
	if (dispatch_get_specific(IsOnConnectionQueueKey))
	{
		// You are attempting to execute a transaction within a transaction.
		// This will result in deadlock.
		// 
		// For more information, see the "Thread Safety" wiki page:
		// https://github.com/yapstudios/YapDatabase/wiki/Thread-Safety#connections-queues--deadlock
		
		@throw [self deadlockDetectionException];
	}
#endif




What is it the problem?
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
What is the error? It just freezes or raises an error?
thumbnail
Salva Tejero, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Junior Member Beiträge: 77 Beitrittsdatum: 13.06.11 Neueste Beiträge
Jose M. Navarro:
What is the error? It just freezes or raises an error?


The application just closes instantly without showing any error
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
Salva Tejero:
Jose M. Navarro:
What is the error? It just freezes or raises an error?


The application just closes instantly without showing any error


Any log in the console?
thumbnail
Salva Tejero, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Junior Member Beiträge: 77 Beitrittsdatum: 13.06.11 Neueste Beiträge
uncaught exception 'YapDatabaseException', reason: 'YapDatabaseConnection[0x15de9f80] - deadlock detection'
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
Added issue too

Thanks!
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
Can you check the ticket?

I tried to reproduce it with a simple project but I couldn't
thumbnail
Salva Tejero, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Junior Member Beiträge: 77 Beitrittsdatum: 13.06.11 Neueste Beiträge
The example works fine.

I think I have found the possible problem:

I hope that you can help me.

In my AssetListView_theme.swift, in the method "override public func doFillLoadedCell(row row: Int, cell: UITableViewCell, object:AnyObject)" I use SessionContext.currentContext?.cacheManager.getImage(..... to get and store "SessionContext.currentContext?.cacheManager.setClean(" an image to set cell background.

When I have remote-first policy all is ok, but when i use cache-first and refresh the component I get the problem. cacheManager doesn't have any transaction active.

Can you help me?
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
Can you paste the code of your doFillLoadedCell?
Or even better: can you share a simple project that reproduces the issue?

Thanks!
thumbnail
Salva Tejero, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Junior Member Beiträge: 77 Beitrittsdatum: 13.06.11 Neueste Beiträge
It's difficult to me extract the functionality

This is the code of the method.

override public func doFillLoadedCell(row row: Int, cell: UITableViewCell, object:AnyObject) {
		if let entry = object as? LiferayScreens.Asset {
            let articleId = entry.attributes["articleId"] as! String
            let keyCache = "\(articleId)-image-cell"
            
            SessionContext.currentContext?.cacheManager.getImage(
                collection: ScreenletName(AssetListScreenlet),
                key: keyCache) {
                    
                    if( $0 != nil){
                        let cellAux = cell as! TextAndBackgroundTableViewCell
                        cellAux._backgroundIMV.image = $0
                    }else{
                        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), {
                            let myConfigClass:ConfigurationLoader = ConfigurationLoader()
        
                            myConfigClass.methodGetXmlElementInString(SessionContext.createSessionFromCurrentSession(), withGroupId: entry.groupId, withArticleId: (entry.attributes["articleId"] as! String), withLocale: "es_ES", withClave: "imagen", withTipo: "doc", { (result) in
                            let imageData = NSData(base64EncodedString: result, options: NSDataBase64DecodingOptions(rawValue: 0))
                            cell.imageView?.image = UIImage(data: imageData!)
                            
                            SessionContext.currentContext?.cacheManager.setClean(
                                collection: ScreenletName(AssetListScreenlet),
                                key: keyCache,
                                value: UIImage(data: imageData!)!,
                                attributes: [
                                    "classPk": entry.attributes["articleId"] as! String])
                            
                                (cell as! TextAndBackgroundTableViewCell)._backgroundIMV.image = UIImage(data: imageData!)
                            })
                        })
                    
                    }
            }
             
            cell.detailTextLabel?.text = entry.title
            cell.textLabel?.text = entry.title
			cell.accessoryType = .DisclosureIndicator
			cell.accessoryView = nil
		}
	}



Basically, the method search in the cache if it has a image with the key. If it isn't exists, then I search in Liferay SDK custom method the image in structure field. This method return a documentLibrary image in base64String, Then, I put the image into cache and I show it in the cell.

The problem is cacheManager hasn't a transaction because I use first-cache in Screemlet load.
thumbnail
Jose M. Navarro, geändert vor 7 Jahren.

RE: Deadlock with CacheFirst

Regular Member Beiträge: 138 Beitrittsdatum: 24.01.14 Neueste Beiträge
I tried to reproduce it without luck.

Is the error raised in the setClean call? If so, try to wrap the setClean method in a dispatch_async with main queue.

Also, be careful with your images. You're creating 3 UIImage objects, when only one is enough (this is unrelated).