Fixed up a potential threading issue with the sync configuration logic

Moved all the sync configuration calls to be within the existing 'write' blocks instead of waiting until the completion
pull/602/head
Morgan Pretty 3 years ago
parent 5bb3bd7bc1
commit b815a9f348

@ -48,15 +48,14 @@ extension ConversationVC : InputViewDelegate, MessageCellDelegate, ContextMenuAc
self.blockedBanner.alpha = 0 self.blockedBanner.alpha = 0
}, completion: { _ in }, completion: { _ in
if let contact: Contact = Storage.shared.getContact(with: publicKey) { if let contact: Contact = Storage.shared.getContact(with: publicKey) {
Storage.shared.write( Storage.shared.write { transaction in
with: { transaction in guard let transaction = transaction as? YapDatabaseReadWriteTransaction else { return }
contact.isBlocked = false
Storage.shared.setContact(contact, using: transaction) contact.isBlocked = false
}, Storage.shared.setContact(contact, using: transaction)
completion: {
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete() MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
} }
)
} }
}) })
} }
@ -1149,6 +1148,9 @@ extension ConversationVC {
contact.didApproveMe = (contact.didApproveMe || !isNewThread) contact.didApproveMe = (contact.didApproveMe || !isNewThread)
Storage.shared.setContact(contact, using: transaction) Storage.shared.setContact(contact, using: transaction)
// Send a sync message with the details of the contact
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
// Hide the 'messageRequestView' since the request has been approved and force a config // Hide the 'messageRequestView' since the request has been approved and force a config
// sync to propagate the contact approval state (both must run on the main thread) // sync to propagate the contact approval state (both must run on the main thread)
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
@ -1182,9 +1184,6 @@ extension ConversationVC {
newViewControllers.remove(at: messageRequestsIndex) newViewControllers.remove(at: messageRequestsIndex)
self?.navigationController?.setViewControllers(newViewControllers, animated: false) self?.navigationController?.setViewControllers(newViewControllers, animated: false)
} }
// Send a sync message with the details of the contact
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
} }
} }
} }
@ -1245,11 +1244,11 @@ extension ConversationVC {
// Delete all thread content // Delete all thread content
self?.thread.removeAllThreadInteractions(with: transaction) self?.thread.removeAllThreadInteractions(with: transaction)
self?.thread.remove(with: transaction) self?.thread.remove(with: transaction)
// Force a config sync and pop to the previous screen (both must run on the main thread)
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}, },
completion: { [weak self] in completion: { [weak self] in
// Force a config sync and pop to the previous screen (both must run on the main thread)
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
DispatchQueue.main.async { DispatchQueue.main.async {
self?.navigationController?.popViewController(animated: true) self?.navigationController?.popViewController(animated: true)
} }

@ -1,5 +1,6 @@
import SessionMessagingKit
final class BlockedModal : Modal { final class BlockedModal: Modal {
private let publicKey: String private let publicKey: String
// MARK: Lifecycle // MARK: Lifecycle
@ -65,19 +66,16 @@ final class BlockedModal : Modal {
@objc private func unblock() { @objc private func unblock() {
let publicKey: String = self.publicKey let publicKey: String = self.publicKey
Storage.shared.write( Storage.shared.write { transaction in
with: { transaction in guard let transaction = transaction as? YapDatabaseReadWriteTransaction, let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else {
guard let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else { return
return
}
contact.isBlocked = false
Storage.shared.setContact(contact, using: transaction)
},
completion: {
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
} }
)
contact.isBlocked = false
Storage.shared.setContact(contact, using: transaction as Any)
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}
presentingViewController?.dismiss(animated: true, completion: nil) presentingViewController?.dismiss(animated: true, completion: nil)
} }

@ -511,19 +511,19 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
let block = UITableViewRowAction(style: .normal, title: NSLocalizedString("BLOCK_LIST_BLOCK_BUTTON", comment: "")) { _, _ in let block = UITableViewRowAction(style: .normal, title: NSLocalizedString("BLOCK_LIST_BLOCK_BUTTON", comment: "")) { _, _ in
Storage.shared.write( Storage.shared.write(
with: { transaction in with: { transaction in
guard let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else { guard let transaction = transaction as? YapDatabaseReadWriteTransaction, let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else {
return return
} }
contact.isBlocked = true contact.isBlocked = true
Storage.shared.setContact(contact, using: transaction) Storage.shared.setContact(contact, using: transaction as Any)
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}, },
completion: { completion: {
DispatchQueue.main.async { DispatchQueue.main.async {
tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade) tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade)
} }
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
} }
) )
} }
@ -531,19 +531,19 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
let unblock = UITableViewRowAction(style: .normal, title: NSLocalizedString("BLOCK_LIST_UNBLOCK_BUTTON", comment: "")) { _, _ in let unblock = UITableViewRowAction(style: .normal, title: NSLocalizedString("BLOCK_LIST_UNBLOCK_BUTTON", comment: "")) { _, _ in
Storage.shared.write( Storage.shared.write(
with: { transaction in with: { transaction in
guard let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else { guard let transaction = transaction as? YapDatabaseReadWriteTransaction, let contact: Contact = Storage.shared.getContact(with: publicKey, using: transaction) else {
return return
} }
contact.isBlocked = false contact.isBlocked = false
Storage.shared.setContact(contact, using: transaction) Storage.shared.setContact(contact, using: transaction as Any)
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}, },
completion: { completion: {
DispatchQueue.main.async { DispatchQueue.main.async {
tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade) tableView.reloadRows(at: [ indexPath ], with: UITableView.RowAnimation.fade)
} }
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
} }
) )
} }

@ -336,38 +336,35 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
let alertVC: UIAlertController = UIAlertController(title: NSLocalizedString("MESSAGE_REQUESTS_CLEAR_ALL_CONFIRMATION_TITLE", comment: ""), message: nil, preferredStyle: .actionSheet) let alertVC: UIAlertController = UIAlertController(title: NSLocalizedString("MESSAGE_REQUESTS_CLEAR_ALL_CONFIRMATION_TITLE", comment: ""), message: nil, preferredStyle: .actionSheet)
alertVC.addAction(UIAlertAction(title: NSLocalizedString("MESSAGE_REQUESTS_CLEAR_ALL_CONFIRMATION_ACTON", comment: ""), style: .destructive) { _ in alertVC.addAction(UIAlertAction(title: NSLocalizedString("MESSAGE_REQUESTS_CLEAR_ALL_CONFIRMATION_ACTON", comment: ""), style: .destructive) { _ in
// Clear the requests // Clear the requests
Storage.write( Storage.write { [weak self] transaction in
with: { [weak self] transaction in threads.forEach { thread in
threads.forEach { thread in if let uniqueId: String = thread.uniqueId {
if let uniqueId: String = thread.uniqueId { Storage.shared.cancelPendingMessageSendJobs(for: uniqueId, using: transaction)
Storage.shared.cancelPendingMessageSendJobs(for: uniqueId, using: transaction) }
}
self?.updateContactAndThread(thread: thread, with: transaction) { threadNeedsSync in
self?.updateContactAndThread(thread: thread, with: transaction) { threadNeedsSync in if threadNeedsSync {
if threadNeedsSync {
needsSync = true
}
}
// Block the contact
if
let sessionId: String = (thread as? TSContactThread)?.contactSessionID(),
!thread.isBlocked(),
let contact: Contact = Storage.shared.getContact(with: sessionId, using: transaction)
{
contact.isBlocked = true
Storage.shared.setContact(contact, using: transaction)
needsSync = true needsSync = true
} }
} }
},
completion: { // Block the contact
// Force a config sync if
if needsSync { let sessionId: String = (thread as? TSContactThread)?.contactSessionID(),
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete() !thread.isBlocked(),
let contact: Contact = Storage.shared.getContact(with: sessionId, using: transaction)
{
contact.isBlocked = true
Storage.shared.setContact(contact, using: transaction)
needsSync = true
} }
} }
)
// Force a config sync
if needsSync {
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}
}
}) })
alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel, handler: nil)) alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel, handler: nil))
self.present(alertVC, animated: true, completion: nil) self.present(alertVC, animated: true, completion: nil)
@ -378,26 +375,23 @@ class MessageRequestsViewController: BaseVC, UITableViewDelegate, UITableViewDat
let alertVC: UIAlertController = UIAlertController(title: NSLocalizedString("MESSAGE_REQUESTS_DELETE_CONFIRMATION_ACTON", comment: ""), message: nil, preferredStyle: .actionSheet) let alertVC: UIAlertController = UIAlertController(title: NSLocalizedString("MESSAGE_REQUESTS_DELETE_CONFIRMATION_ACTON", comment: ""), message: nil, preferredStyle: .actionSheet)
alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { _ in alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_DELETE_TITLE", comment: ""), style: .destructive) { _ in
Storage.write( Storage.write { [weak self] transaction in
with: { [weak self] transaction in Storage.shared.cancelPendingMessageSendJobs(for: uniqueId, using: transaction)
Storage.shared.cancelPendingMessageSendJobs(for: uniqueId, using: transaction) self?.updateContactAndThread(thread: thread, with: transaction)
self?.updateContactAndThread(thread: thread, with: transaction)
// Block the contact
// Block the contact if
if let sessionId: String = (thread as? TSContactThread)?.contactSessionID(),
let sessionId: String = (thread as? TSContactThread)?.contactSessionID(), !thread.isBlocked(),
!thread.isBlocked(), let contact: Contact = Storage.shared.getContact(with: sessionId, using: transaction)
let contact: Contact = Storage.shared.getContact(with: sessionId, using: transaction) {
{ contact.isBlocked = true
contact.isBlocked = true Storage.shared.setContact(contact, using: transaction)
Storage.shared.setContact(contact, using: transaction)
}
},
completion: {
// Force a config sync
MessageSender.syncConfiguration(forceSyncNow: true).retainUntilComplete()
} }
)
// Force a config sync
MessageSender.syncConfiguration(forceSyncNow: true, with: transaction).retainUntilComplete()
}
}) })
alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel, handler: nil)) alertVC.addAction(UIAlertAction(title: NSLocalizedString("TXT_CANCEL_TITLE", comment: ""), style: .cancel, handler: nil))
self.present(alertVC, animated: true, completion: nil) self.present(alertVC, animated: true, completion: nil)

Loading…
Cancel
Save