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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -5,7 +5,8 @@ namespace Bit.Core.Abstractions
{
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 Unsubscribe(string id);
}

View file

@ -8,24 +8,58 @@ namespace Bit.App.Services
{
public class BroadcasterService : IBroadcasterService
{
private readonly ILogger _logger;
private readonly Dictionary<string, Action<Message>> _subscribers = new Dictionary<string, Action<Message>>();
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)
{
if (!string.IsNullOrWhiteSpace(id))
{
if (_subscribers.ContainsKey(id))
{
Task.Run(() => _subscribers[id].Invoke(message));
}
return;
}
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)
{
lock (_myLock)
{
if (_subscribers.ContainsKey(id))
{
_subscribers[id] = messageCallback;
}
else
{
_subscribers.Add(id, messageCallback);
}
}
}
public void Unsubscribe(string id)

View file

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

View file

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

View file

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