Improved BroadcastService and added try...catch on async void callbacks (#1917)

This commit is contained in:
Federico Maccaroni 2022-07-05 18:14:10 -03:00 committed by GitHub
parent dbc1e5ea3e
commit 448cce38e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 335 additions and 257 deletions

View file

@ -99,12 +99,13 @@ namespace Bit.Droid
{ {
ServiceContainer.Register<INativeLogService>("nativeLogService", new AndroidLogService()); ServiceContainer.Register<INativeLogService>("nativeLogService", new AndroidLogService());
#if FDROID #if FDROID
ServiceContainer.Register<ILogger>("logger", new StubLogger()); var logger = new StubLogger();
#elif DEBUG #elif DEBUG
ServiceContainer.Register<ILogger>("logger", DebugLogger.Instance); var logger = DebugLogger.Instance;
#else #else
ServiceContainer.Register<ILogger>("logger", Logger.Instance); var logger = Logger.Instance;
#endif #endif
ServiceContainer.Register("logger", logger);
// Note: This might cause a race condition. Investigate more. // Note: This might cause a race condition. Investigate more.
Task.Run(() => Task.Run(() =>
@ -124,7 +125,7 @@ namespace Bit.Droid
var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db")); var liteDbStorage = new LiteDbStorageService(Path.Combine(documentsPath, "bitwarden.db"));
var localizeService = new LocalizeService(); var localizeService = new LocalizeService();
var broadcasterService = new BroadcasterService(); var broadcasterService = new BroadcasterService(logger);
var messagingService = new MobileBroadcasterMessagingService(broadcasterService); var messagingService = new MobileBroadcasterMessagingService(broadcasterService);
var i18nService = new MobileI18nService(localizeService.GetCurrentCultureInfo()); var i18nService = new MobileI18nService(localizeService.GetCurrentCultureInfo());
var secureStorageService = new SecureStorageService(); var secureStorageService = new SecureStorageService();

View file

@ -10,6 +10,7 @@ using Bit.App.Utilities.AccountManagement;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
using Xamarin.Forms.Xaml; using Xamarin.Forms.Xaml;
@ -55,6 +56,8 @@ namespace Bit.App
Bootstrap(); Bootstrap();
_broadcasterService.Subscribe(nameof(App), async (message) => _broadcasterService.Subscribe(nameof(App), async (message) =>
{
try
{ {
if (message.Command == "showDialog") if (message.Command == "showDialog")
{ {
@ -137,6 +140,11 @@ namespace Bit.App
new NavigationPage(new RemoveMasterPasswordPage())); new NavigationPage(new RemoveMasterPasswordPage()));
}); });
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
} }

View file

@ -54,7 +54,7 @@ namespace Bit.App.Pages
{ {
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(); _vm.AvatarImageSource = await GetAvatarImageSourceAsync();
} }
_broadcasterService.Subscribe(nameof(HomePage), async (message) => _broadcasterService.Subscribe(nameof(HomePage), (message) =>
{ {
if (message.Command == "updatedTheme") if (message.Command == "updatedTheme")
{ {

View file

@ -5,6 +5,7 @@ using Bit.App.Controls;
using Bit.App.Models; using Bit.App.Models;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
@ -67,6 +68,8 @@ namespace Bit.App.Pages
} }
_broadcasterService.Subscribe(_pageName, async (message) => _broadcasterService.Subscribe(_pageName, async (message) =>
{
try
{ {
if (message.Command == "syncStarted") if (message.Command == "syncStarted")
{ {
@ -84,6 +87,11 @@ namespace Bit.App.Pages
} }
}); });
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
await LoadOnAppearedAsync(_mainLayout, false, async () => await LoadOnAppearedAsync(_mainLayout, false, async () =>

View file

@ -6,6 +6,7 @@ using Bit.App.Models;
using Bit.App.Utilities; using Bit.App.Utilities;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
@ -54,6 +55,8 @@ namespace Bit.App.Pages
_vm.AvatarImageSource = await GetAvatarImageSourceAsync(); _vm.AvatarImageSource = await GetAvatarImageSourceAsync();
_broadcasterService.Subscribe(nameof(AutofillCiphersPage), async (message) => _broadcasterService.Subscribe(nameof(AutofillCiphersPage), async (message) =>
{
try
{ {
if (message.Command == "syncStarted") if (message.Command == "syncStarted")
{ {
@ -71,6 +74,11 @@ namespace Bit.App.Pages
} }
}); });
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
await LoadOnAppearedAsync(_mainLayout, false, async () => await LoadOnAppearedAsync(_mainLayout, false, async () =>

View file

@ -7,6 +7,7 @@ using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Enums; using Bit.Core.Enums;
using Bit.Core.Models.Data; using Bit.Core.Models.Data;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
@ -94,6 +95,8 @@ namespace Bit.App.Pages
} }
_broadcasterService.Subscribe(_pageName, async (message) => _broadcasterService.Subscribe(_pageName, async (message) =>
{
try
{ {
if (message.Command == "syncStarted") if (message.Command == "syncStarted")
{ {
@ -111,6 +114,11 @@ namespace Bit.App.Pages
} }
}); });
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
await LoadOnAppearedAsync(_mainLayout, false, async () => await LoadOnAppearedAsync(_mainLayout, false, async () =>

View file

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Bit.App.Resources; using Bit.App.Resources;
using Bit.Core.Abstractions; using Bit.Core.Abstractions;
using Bit.Core.Services;
using Bit.Core.Utilities; using Bit.Core.Utilities;
using Xamarin.Forms; using Xamarin.Forms;
@ -55,6 +56,8 @@ namespace Bit.App.Pages
} }
_broadcasterService.Subscribe(nameof(ViewPage), async (message) => _broadcasterService.Subscribe(nameof(ViewPage), async (message) =>
{
try
{ {
if (message.Command == "syncStarted") if (message.Command == "syncStarted")
{ {
@ -88,6 +91,11 @@ namespace Bit.App.Pages
_vm.SaveFileSelected(data.Item1, data.Item2); _vm.SaveFileSelected(data.Item1, data.Item2);
}); });
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
await LoadOnAppearedAsync(_scrollView, true, async () => await LoadOnAppearedAsync(_scrollView, true, async () =>
{ {

View file

@ -5,7 +5,8 @@ namespace Bit.Core.Abstractions
{ {
public interface IBroadcasterService public interface IBroadcasterService
{ {
void Send(Message message, string id = null); void Send(Message message);
void Send(Message message, string id);
void Subscribe(string id, Action<Message> messageCallback); void Subscribe(string id, Action<Message> messageCallback);
void Unsubscribe(string id); void Unsubscribe(string id);
} }

View file

@ -8,24 +8,58 @@ namespace Bit.App.Services
{ {
public class BroadcasterService : IBroadcasterService public class BroadcasterService : IBroadcasterService
{ {
private readonly ILogger _logger;
private readonly Dictionary<string, Action<Message>> _subscribers = new Dictionary<string, Action<Message>>(); private readonly Dictionary<string, Action<Message>> _subscribers = new Dictionary<string, Action<Message>>();
private object _myLock = new object(); private object _myLock = new object();
public void Send(Message message, string id = null) public BroadcasterService(ILogger logger)
{
_logger = logger;
}
public void Send(Message message)
{ {
lock (_myLock) lock (_myLock)
{ {
if (!string.IsNullOrWhiteSpace(id))
{
if (_subscribers.ContainsKey(id))
{
Task.Run(() => _subscribers[id].Invoke(message));
}
return;
}
foreach (var sub in _subscribers) foreach (var sub in _subscribers)
{ {
Task.Run(() => sub.Value.Invoke(message)); Task.Run(() =>
{
try
{
sub.Value(message);
}
catch (Exception ex)
{
_logger.Exception(ex);
}
});
}
}
}
public void Send(Message message, string id)
{
if (string.IsNullOrWhiteSpace(id))
{
return;
}
lock (_myLock)
{
if (_subscribers.TryGetValue(id, out var action))
{
Task.Run(() =>
{
try
{
action(message);
}
catch (Exception ex)
{
_logger.Exception(ex);
}
});
} }
} }
} }
@ -33,16 +67,9 @@ namespace Bit.App.Services
public void Subscribe(string id, Action<Message> messageCallback) public void Subscribe(string id, Action<Message> messageCallback)
{ {
lock (_myLock) lock (_myLock)
{
if (_subscribers.ContainsKey(id))
{ {
_subscribers[id] = messageCallback; _subscribers[id] = messageCallback;
} }
else
{
_subscribers.Add(id, messageCallback);
}
}
} }
public void Unsubscribe(string id) public void Unsubscribe(string id)

View file

@ -21,7 +21,7 @@ namespace Bit.iOS.Core.Renderers
public CustomTabbedRenderer() public CustomTabbedRenderer()
{ {
_broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService"); _broadcasterService = ServiceContainer.Resolve<IBroadcasterService>("broadcasterService");
_broadcasterService.Subscribe(nameof(CustomTabbedRenderer), async (message) => _broadcasterService.Subscribe(nameof(CustomTabbedRenderer), (message) =>
{ {
if (message.Command == "updatedTheme") if (message.Command == "updatedTheme")
{ {

View file

@ -38,13 +38,15 @@ namespace Bit.iOS.Core.Utilities
ServiceContainer.Register<INativeLogService>("nativeLogService", new ConsoleLogService()); ServiceContainer.Register<INativeLogService>("nativeLogService", new ConsoleLogService());
} }
ILogger logger = null;
if (ServiceContainer.Resolve<ILogger>("logger", true) == null) if (ServiceContainer.Resolve<ILogger>("logger", true) == null)
{ {
#if DEBUG #if DEBUG
ServiceContainer.Register<ILogger>("logger", DebugLogger.Instance); logger = DebugLogger.Instance;
#else #else
ServiceContainer.Register<ILogger>("logger", Logger.Instance); logger = Logger.Instance;
#endif #endif
ServiceContainer.Register("logger", logger);
} }
var preferencesStorage = new PreferencesStorageService(AppGroupId); var preferencesStorage = new PreferencesStorageService(AppGroupId);
@ -52,7 +54,7 @@ namespace Bit.iOS.Core.Utilities
var liteDbStorage = new LiteDbStorageService( var liteDbStorage = new LiteDbStorageService(
Path.Combine(appGroupContainer.Path, "Library", "bitwarden.db")); Path.Combine(appGroupContainer.Path, "Library", "bitwarden.db"));
var localizeService = new LocalizeService(); var localizeService = new LocalizeService();
var broadcasterService = new BroadcasterService(); var broadcasterService = new BroadcasterService(logger);
var messagingService = new MobileBroadcasterMessagingService(broadcasterService); var messagingService = new MobileBroadcasterMessagingService(broadcasterService);
var i18nService = new MobileI18nService(localizeService.GetCurrentCultureInfo()); var i18nService = new MobileI18nService(localizeService.GetCurrentCultureInfo());
var secureStorageService = new KeyChainStorageService(AppId, AccessGroup, var secureStorageService = new KeyChainStorageService(AppId, AccessGroup,

View file

@ -58,6 +58,8 @@ namespace Bit.iOS
ZXing.Net.Mobile.Forms.iOS.Platform.Init(); ZXing.Net.Mobile.Forms.iOS.Platform.Init();
_broadcasterService.Subscribe(nameof(AppDelegate), async (message) => _broadcasterService.Subscribe(nameof(AppDelegate), async (message) =>
{
try
{ {
if (message.Command == "startEventTimer") if (message.Command == "startEventTimer")
{ {
@ -168,6 +170,11 @@ namespace Bit.iOS
await ASHelpers.ReplaceAllIdentities(); await ASHelpers.ReplaceAllIdentities();
} }
} }
}
catch (Exception ex)
{
LoggerHelper.LogEvenIfCantBeResolved(ex);
}
}); });
return base.FinishedLaunching(app, options); return base.FinishedLaunching(app, options);