update: RemoteConfig 拉取修复 Review

--story=1021111 --user=yufei.hu 【中台】【Fix】修复 RemoteConfig 接口中立即获取线上更新配置不生效的 BUG https://www.tapd.cn/33527076/s/1160717

Signed-off-by: huyufei <yufei.hu@castbox.fm>
胡宇飞 2024-07-30 21:48:03 +08:00
parent cd83fd8bab
commit ada48d7c0e
1 changed files with 64 additions and 107 deletions

View File

@ -17,8 +17,8 @@ namespace Guru
/// </summary> /// </summary>
public class RemoteConfigManager public class RemoteConfigManager
{ {
public const double DefaultUpdateHours = 2; private const double DefaultUpdateHours = 2;
public const double DefaultFetchTimeout = 15; private const double DefaultFetchTimeout = 15;
internal const string Tag = "[Remote]"; internal const string Tag = "[Remote]";
private static bool _initOnce = false; private static bool _initOnce = false;
private static RemoteConfigManager _instance; private static RemoteConfigManager _instance;
@ -29,7 +29,7 @@ namespace Guru
private static double _fetchIntervalHours = DefaultUpdateHours; private static double _fetchIntervalHours = DefaultUpdateHours;
private RemoteConfigModel _model; private RemoteConfigModel _model;
internal RemoteConfigModel Model => _model ??= RemoteConfigModel.LoadOrCreate(); private RemoteConfigModel Model => _model ??= RemoteConfigModel.LoadOrCreate();
private static Dictionary<string, object> _defaultValues; private static Dictionary<string, object> _defaultValues;
@ -87,7 +87,7 @@ namespace Guru
MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000) MinimumFetchInternalInMilliseconds = (ulong)(_fetchIntervalHours * 60 * 60 * 1000)
}); });
_firebaseRemote.OnConfigUpdateListener += OnConfigUpdatedHandler; _firebaseRemote.OnConfigUpdateListener += OnFirebaseConfigUpdatedHandler;
// 设置默认值 // 设置默认值
AppendDefaultValues(defaults); AppendDefaultValues(defaults);
@ -97,143 +97,99 @@ namespace Guru
_changeEvents = new Dictionary<string, Action<string,string>>(30); _changeEvents = new Dictionary<string, Action<string,string>>(30);
// 立即拉取所有的配置 // 立即拉取所有的配置
FetchAllConfigsImmediately(); FetchAll(true);
} }
private void AppendDefaultValues(Dictionary<string, object> defaults) private void AppendDefaultValues(Dictionary<string, object> defaults)
{ {
if (defaults != null) if (defaults == null) return;
if(_defaultValues == null) _defaultValues = new Dictionary<string, object>(20);
for(int i = 0; i < defaults.Keys.Count; i++)
{ {
if(_defaultValues == null) _defaultValues = new Dictionary<string, object>(20); string key = defaults.Keys.ElementAt(i);
string key; object value = defaults.Values.ElementAt(i);
object value; _defaultValues[key] = value;
for(int i = 0; i < defaults.Keys.Count; i++)
{
key = defaults.Keys.ElementAt(i);
value = defaults.Values.ElementAt(i);
_defaultValues[key] = value;
}
_firebaseRemote?.SetDefaultsAsync(_defaultValues);
} }
_firebaseRemote?.SetDefaultsAsync(_defaultValues);
} }
/// <summary>
/// 拉取所有Remote 配置并激活 (默认激活间隔 2 小时)
/// 官方文档:
/// https://firebase.google.com/docs/reference/unity/class/firebase/remote-config/firebase-remote-config#class_firebase_1_1_remote_config_1_1_firebase_remote_config_1a55b6f0ebc2b457e9c0e2ac7c52cc87fa
/// </summary>
/// <param name="immediately">如果=true相当于执行一次 FetchAndActivate 立即激活拉取到的配置</param>
private void FetchAllConfigs(bool immediately = false) private void FetchAllConfigs(bool immediately = false)
{ {
var span = TimeSpan.FromHours(_fetchIntervalHours); var span = TimeSpan.FromHours(_fetchIntervalHours);
bool success = true;
// if (_isDebug || immediately)
// {
// FetchAllConfigsImmediately();
// return;
// }
if (_isDebug || immediately) if (_isDebug || immediately)
{ {
span = TimeSpan.Zero; span = TimeSpan.Zero;
} }
_firebaseRemote.FetchAsync(span) _firebaseRemote.FetchAsync(span)
.ContinueWithOnMainThread(task => .ContinueWithOnMainThread(fetchTask =>
{ {
if (task.IsFaulted || task.IsCanceled) if (fetchTask.IsFaulted || fetchTask.IsCanceled)
{ {
string res = task.IsFaulted? "Faulted" : "Canceled"; string res = fetchTask.IsFaulted? "Faulted" : "Canceled";
LogE($" --- Fetch AllConfigs fails: {res}"); LogE($" --- Fetch AllConfigs fails: {res}");
success = false; OnFetchCompleted?.Invoke(false);
return;
} }
if (success) _firebaseRemote.ActivateAsync()
.ContinueWithOnMainThread(activateTask =>
{ {
_firebaseRemote.ActivateAsync() if (activateTask.IsFaulted || activateTask.IsCanceled)
.ContinueWithOnMainThread(task =>
{ {
if (task.IsFaulted || task.IsCanceled) string res = activateTask.IsFaulted? "Faulted" : "Canceled";
{ LogE($" --- Active AllConfigs fails: {res}");
success = false; OnFetchCompleted?.Invoke(false);
string res = task.IsFaulted? "Faulted" : "Canceled"; return;
LogE($" --- Active AllConfigs fails: {res}"); }
}
else LogI($"[REMOTE] --- ActiveAsync success!");
{
success = true;
}
LogI($"[REMOTE] --- ActiveAsync success: {success}");
OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success);
});
}
else
{
OnFetchDataCompleted(); OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success); OnFetchCompleted?.Invoke(true);
} });
}); });
} }
/// <summary>
/// 立即拉取所有的配置
/// </summary>
private void FetchAllConfigsImmediately()
{
bool success = true;
_firebaseRemote.FetchAndActivateAsync()
.ContinueWithOnMainThread(task =>
{
if (task.IsFaulted || task.IsCanceled)
{
success = false;
string res = task.IsFaulted? "Faulted" : "Canceled";
LogE($" --- Fetch AllConfigs fails: {res}");
}
else
{
success = true;
LogI($"{Tag} --- FetchAndActivateAsync success");
}
LogI($"{Tag} --- FetchAndActivateAsync success: {success}");
OnFetchDataCompleted();
OnFetchCompleted?.Invoke(success);
});
}
/// <summary> /// <summary>
/// 获取值更新回调 /// 获取值更新回调
/// </summary> /// </summary>
/// <param name="sender"></param> /// <param name="sender"></param>
/// <param name="updateEvent"></param> /// <param name="updateEvent"></param>
private void OnConfigUpdatedHandler(object sender, ConfigUpdateEventArgs updateEvent) private void OnFirebaseConfigUpdatedHandler(object sender, ConfigUpdateEventArgs updateEvent)
{ {
if (updateEvent.Error != RemoteConfigError.None) if (updateEvent.Error != RemoteConfigError.None)
{ {
Debug.LogError($"{Tag} --- RemoteConfigError: {updateEvent.Error}"); Debug.LogError($"{Tag} --- RemoteConfigError: {updateEvent.Error}");
return;
} }
else
_firebaseRemote.ActivateAsync().ContinueWithOnMainThread(task =>
{ {
_firebaseRemote.ActivateAsync().ContinueWithOnMainThread(task => if (!task.IsCompleted) return;
if (updateEvent.UpdatedKeys == null) return;
var updateKeys = updateEvent.UpdatedKeys.ToArray();
int count = updateEvent.UpdatedKeys.Count();
for(int i = 0; i < count; i++)
{ {
if (task.IsCompleted) string key = updateEvent.UpdatedKeys.ElementAt(i);
if (_changeEvents.TryGetValue(updateKeys[i], out var callback))
{ {
if (updateEvent.UpdatedKeys != null) callback?.Invoke(key, _firebaseRemote.GetValue(key).StringValue);
{ }
var updateKeys = updateEvent.UpdatedKeys.ToArray(); }
string key = ""; });
int i = 0;
int count = updateEvent.UpdatedKeys.Count();
while (i < count)
{
key = updateEvent.UpdatedKeys.ElementAt(i);
if (_changeEvents.TryGetValue(updateKeys[i], out var callback))
{
callback?.Invoke(key, _firebaseRemote.GetValue(key).StringValue);
}
i++;
}
}
}
});
}
} }
@ -268,13 +224,11 @@ namespace Guru
var values = _firebaseRemote.AllValues; var values = _firebaseRemote.AllValues;
var updates = new Dictionary<string, string>(values.Count); var updates = new Dictionary<string, string>(values.Count);
var configs = new Dictionary<string, string>(values.Count); var configs = new Dictionary<string, string>(values.Count);
ConfigValue value;
string key, str;
for (int i = 0; i < values.Keys.Count; i++) for (int i = 0; i < values.Keys.Count; i++)
{ {
key = values.Keys.ElementAt(i); var key = values.Keys.ElementAt(i);
value = values.Values.ElementAt(i); var value = values.Values.ElementAt(i);
str = value.StringValue; var str = value.StringValue;
updates[key] = str; updates[key] = str;
if (IsRemoteConfigStr(str)) if (IsRemoteConfigStr(str))
@ -566,7 +520,10 @@ namespace Guru
return false; return false;
} }
/// <summary>
/// 将所有云控值变化的参数通过回调通知给订阅者
/// </summary>
/// <param name="updates"></param>
private void DispatchUpdateValues(Dictionary<string, string> updates) private void DispatchUpdateValues(Dictionary<string, string> updates)
{ {
Dictionary<string, string> changes = new Dictionary<string, string>(updates.Count); Dictionary<string, string> changes = new Dictionary<string, string>(updates.Count);