Hydrate missing actor and org records from live data
- Require actor records to exist in storage before hot load - Fall back to player snapshots to fill missing actor fields and org defaults - Refresh org member names when a better value is available - Keep bootstrap extension calls on the direct path by default
This commit is contained in:
parent
1d54cc70c3
commit
cd3e937cdc
@ -55,7 +55,7 @@ if (isNil QGVAR(VGRepository)) then { call FUNC(initVGRepository); };
|
|||||||
}] call CFUNC(addEventHandler);
|
}] call CFUNC(addEventHandler);
|
||||||
|
|
||||||
[{
|
[{
|
||||||
EGVAR(bank,BankRepository) get "isLoaded";
|
EGVAR(actor,ActorRepository) get "isLoaded";
|
||||||
}, {
|
}, {
|
||||||
[QGVAR(initGarage), []] call CFUNC(localEvent);
|
[QGVAR(initGarage), []] call CFUNC(localEvent);
|
||||||
}] call CFUNC(waitUntilAndExecute);
|
}] call CFUNC(waitUntilAndExecute);
|
||||||
|
|||||||
@ -36,7 +36,7 @@ if (isNil QGVAR(VARepository)) then { call FUNC(initVARepository); };
|
|||||||
}] call CFUNC(addEventHandler);
|
}] call CFUNC(addEventHandler);
|
||||||
|
|
||||||
[{
|
[{
|
||||||
EGVAR(garage,GarageRepository) get "isLoaded";
|
EGVAR(actor,ActorRepository) get "isLoaded";
|
||||||
}, {
|
}, {
|
||||||
[QGVAR(initLocker), []] call CFUNC(localEvent);
|
[QGVAR(initLocker), []] call CFUNC(localEvent);
|
||||||
}] call CFUNC(waitUntilAndExecute);
|
}] call CFUNC(waitUntilAndExecute);
|
||||||
|
|||||||
@ -51,7 +51,7 @@ if (isNil QGVAR(OrgUIBridge)) then { call FUNC(initUIBridge); };
|
|||||||
}] call CFUNC(addEventHandler);
|
}] call CFUNC(addEventHandler);
|
||||||
|
|
||||||
[{
|
[{
|
||||||
EGVAR(locker,VARepository) get "isLoaded";
|
EGVAR(actor,ActorRepository) get "isLoaded";
|
||||||
}, {
|
}, {
|
||||||
[QGVAR(initOrg), []] call CFUNC(localEvent);
|
[QGVAR(initOrg), []] call CFUNC(localEvent);
|
||||||
}] call CFUNC(waitUntilAndExecute);
|
}] call CFUNC(waitUntilAndExecute);
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
* File: fnc_initActorStore.sqf
|
* File: fnc_initActorStore.sqf
|
||||||
* Author: IDSolutions
|
* Author: IDSolutions
|
||||||
* Date: 2025-12-17
|
* Date: 2025-12-17
|
||||||
* Last Update: 2026-04-01
|
* Last Update: 2026-04-05
|
||||||
* Public: Yes
|
* Public: Yes
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@ -153,12 +153,140 @@ GVAR(ActorBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
params [["_uid", "", [""]], ["_initialize", false, [false]]];
|
params [["_uid", "", [""]], ["_initialize", false, [false]]];
|
||||||
|
|
||||||
if (_uid isEqualTo "") exitWith { createHashMap };
|
if (_uid isEqualTo "") exitWith { createHashMap };
|
||||||
|
if (_initialize) then {
|
||||||
|
private _ensureResult = _self call ["ensurePersistentActor", [_uid]];
|
||||||
|
if !(_ensureResult isEqualType true && { _ensureResult }) exitWith { createHashMap };
|
||||||
|
};
|
||||||
|
|
||||||
private _command = ["actor:hot:get", "actor:hot:init"] select _initialize;
|
private _command = ["actor:hot:get", "actor:hot:init"] select _initialize;
|
||||||
private _actor = _self call ["callHotActor", [_command, [_uid]]];
|
private _actor = _self call ["callHotActor", [_command, [_uid]]];
|
||||||
if (_actor isEqualTo createHashMap) exitWith { _actor };
|
if (_actor isEqualTo createHashMap) exitWith { _actor };
|
||||||
|
|
||||||
_self call ["cacheActor", [_uid, _actor]]
|
_self call ["hydrateActorIfNeeded", [_uid, _actor, true]]
|
||||||
|
}],
|
||||||
|
["ensurePersistentActor", compileFinal {
|
||||||
|
params [["_uid", "", [""]]];
|
||||||
|
|
||||||
|
if (_uid isEqualTo "") exitWith { false };
|
||||||
|
|
||||||
|
["actor:exists", [_uid]] call EFUNC(extension,extCall) params ["_existsResult", "_existsSuccess"];
|
||||||
|
if (!_existsSuccess || { !(_existsResult isEqualType "") }) exitWith {
|
||||||
|
["ERROR", format ["Failed to verify persistent actor state for %1.", _uid]] call EFUNC(common,log);
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (_existsResult isEqualTo "true") exitWith { true };
|
||||||
|
|
||||||
|
private _player = [_uid] call EFUNC(common,getPlayer);
|
||||||
|
private _actor = GVAR(ActorModel) call ["fromPlayer", [_player]];
|
||||||
|
_actor set ["uid", _uid];
|
||||||
|
|
||||||
|
if ((_actor getOrDefault ["organization", ""]) isEqualTo "") then {
|
||||||
|
_actor set ["organization", "default"];
|
||||||
|
};
|
||||||
|
|
||||||
|
private _json = _self call ["toJSON", [_actor]];
|
||||||
|
["actor:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_createResult", "_createSuccess"];
|
||||||
|
|
||||||
|
if (!_createSuccess || { !(_createResult isEqualType "") }) exitWith {
|
||||||
|
["ERROR", format ["Failed to create actor %1 from server snapshot.", _uid]] call EFUNC(common,log);
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((_createResult find "Error:") == 0) exitWith {
|
||||||
|
["ERROR", format ["Actor create for %1 failed: %2", _uid, _createResult]] call EFUNC(common,log);
|
||||||
|
false
|
||||||
|
};
|
||||||
|
|
||||||
|
true
|
||||||
|
}],
|
||||||
|
["hydrateActorIfNeeded", compileFinal {
|
||||||
|
params [["_uid", "", [""]], ["_actor", createHashMap, [createHashMap]], ["_save", true, [false]]];
|
||||||
|
|
||||||
|
if (_uid isEqualTo "" || { !(_actor isEqualType createHashMap) } || { _actor isEqualTo createHashMap }) exitWith {
|
||||||
|
createHashMap
|
||||||
|
};
|
||||||
|
|
||||||
|
private _hydratedActor = GVAR(ActorModel) call ["migrate", [+_actor]];
|
||||||
|
private _defaults = GVAR(ActorModel) call ["defaults", []];
|
||||||
|
private _player = [_uid] call EFUNC(common,getPlayer);
|
||||||
|
private _needsPersist = false;
|
||||||
|
|
||||||
|
if ((_hydratedActor getOrDefault ["uid", ""]) isEqualTo "") then {
|
||||||
|
_hydratedActor set ["uid", _uid];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
if ((_hydratedActor getOrDefault ["organization", ""]) isEqualTo "") then {
|
||||||
|
_hydratedActor set ["organization", "default"];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
private _value = _hydratedActor getOrDefault [_x, ""];
|
||||||
|
if !(_value isEqualType "") then {
|
||||||
|
_hydratedActor set [_x, _defaults getOrDefault [_x, ""]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
} forEach ["phone_number", "email"];
|
||||||
|
|
||||||
|
if (_player isNotEqualTo objNull) then {
|
||||||
|
private _snapshot = GVAR(ActorModel) call ["fromPlayer", [_player]];
|
||||||
|
private _name = _hydratedActor getOrDefault ["name", ""];
|
||||||
|
if (
|
||||||
|
!(_name isEqualType "")
|
||||||
|
|| { _name isEqualTo "" }
|
||||||
|
|| { toLowerANSI _name isEqualTo "unknown" }
|
||||||
|
) then {
|
||||||
|
_hydratedActor set ["name", _snapshot getOrDefault ["name", name _player]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _position = _hydratedActor getOrDefault ["position", []];
|
||||||
|
if !(_position isEqualType [] && { count _position isEqualTo 3 }) then {
|
||||||
|
_hydratedActor set ["position", _snapshot getOrDefault ["position", getPosASL _player]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
private _direction = _hydratedActor getOrDefault ["direction", 0];
|
||||||
|
if !(_direction isEqualType 0) then {
|
||||||
|
_hydratedActor set ["direction", _snapshot getOrDefault ["direction", getDir _player]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
private _fieldValue = _hydratedActor getOrDefault [_x, ""];
|
||||||
|
if (!(_fieldValue isEqualType "") || { _fieldValue isEqualTo "" }) then {
|
||||||
|
_hydratedActor set [_x, _snapshot getOrDefault [_x, _defaults getOrDefault [_x, ""]]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
} forEach ["stance", "rank", "state"];
|
||||||
|
|
||||||
|
private _loadout = _hydratedActor getOrDefault ["loadout", []];
|
||||||
|
if !(_loadout isEqualType [] && { count _loadout > 0 }) then {
|
||||||
|
_hydratedActor set ["loadout", getUnitLoadout _player];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
{
|
||||||
|
private _fieldValue = _hydratedActor getOrDefault [_x, ""];
|
||||||
|
if (!(_fieldValue isEqualType "") || { _fieldValue isEqualTo "" }) then {
|
||||||
|
_hydratedActor set [_x, _defaults getOrDefault [_x, ""]];
|
||||||
|
_needsPersist = true;
|
||||||
|
};
|
||||||
|
} forEach ["stance", "rank", "state"];
|
||||||
|
};
|
||||||
|
|
||||||
|
if !_needsPersist exitWith {
|
||||||
|
_self call ["cacheActor", [_uid, _hydratedActor]]
|
||||||
|
};
|
||||||
|
|
||||||
|
private _updatedActor = _self call ["override", [_uid, _hydratedActor, _save]];
|
||||||
|
if (_updatedActor isEqualType createHashMap && { _updatedActor isNotEqualTo createHashMap }) exitWith {
|
||||||
|
_self call ["cacheActor", [_uid, _updatedActor]]
|
||||||
|
};
|
||||||
|
|
||||||
|
["WARNING", format ["Failed to hydrate actor %1 from player snapshot.", _uid]] call EFUNC(common,log);
|
||||||
|
_self call ["cacheActor", [_uid, _hydratedActor]]
|
||||||
}],
|
}],
|
||||||
["init", compileFinal {
|
["init", compileFinal {
|
||||||
params [["_uid", "", [""]]];
|
params [["_uid", "", [""]]];
|
||||||
@ -182,14 +310,11 @@ GVAR(ActorBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
_finalActor = _self call ["loadHotActor", [_uid, true]];
|
_finalActor = _self call ["loadHotActor", [_uid, true]];
|
||||||
["INFO", format ["Found actor for %1", _uid]] call EFUNC(common,log);
|
["INFO", format ["Found actor for %1", _uid]] call EFUNC(common,log);
|
||||||
} else {
|
} else {
|
||||||
_finalActor = GVAR(ActorModel) call ["fromPlayer", [_player]];
|
if !(_self call ["ensurePersistentActor", [_uid]]) exitWith {
|
||||||
_finalActor set ["uid", _uid];
|
|
||||||
|
|
||||||
private _json = _self call ["toJSON", [_finalActor]];
|
|
||||||
["actor:create", [_uid, _json]] call EFUNC(extension,extCall) params ["_createResult", "_createSuccess"];
|
|
||||||
if (!_createSuccess) exitWith {
|
|
||||||
["ERROR", format ["Failed to create actor %1! Using fallback actor.", _uid]] call EFUNC(common,log);
|
["ERROR", format ["Failed to create actor %1! Using fallback actor.", _uid]] call EFUNC(common,log);
|
||||||
|
|
||||||
|
_finalActor = GVAR(ActorModel) call ["fromPlayer", [_player]];
|
||||||
|
_finalActor set ["uid", _uid];
|
||||||
_finalActor = _self call ["cacheActor", [_uid, _finalActor]];
|
_finalActor = _self call ["cacheActor", [_uid, _finalActor]];
|
||||||
[CRPC(actor,responseInitActor), [_finalActor], _player] call CFUNC(targetEvent);
|
[CRPC(actor,responseInitActor), [_finalActor], _player] call CFUNC(targetEvent);
|
||||||
_finalActor
|
_finalActor
|
||||||
@ -358,6 +483,9 @@ GVAR(ActorBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
_finalActor set ["rank", rank _player];
|
_finalActor set ["rank", rank _player];
|
||||||
_finalActor set ["state", lifeState _player];
|
_finalActor set ["state", lifeState _player];
|
||||||
_finalActor set ["loadout", getUnitLoadout _player];
|
_finalActor set ["loadout", getUnitLoadout _player];
|
||||||
|
if ((_finalActor getOrDefault ["organization", ""]) isEqualTo "") then {
|
||||||
|
_finalActor set ["organization", "default"];
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
["WARNING", format ["No player object found for %1 during actor snapshot, using cached values.", _uid]] call EFUNC(common,log);
|
["WARNING", format ["No player object found for %1 during actor snapshot, using cached values.", _uid]] call EFUNC(common,log);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -31,17 +31,18 @@ private _chunkPrefix = "FORGE_TRANSPORT_CHUNK:";
|
|||||||
private _chunkPrefixLength = count toArray _chunkPrefix;
|
private _chunkPrefixLength = count toArray _chunkPrefix;
|
||||||
private _unsupportedRoutePrefix = "Error: Unsupported transport route";
|
private _unsupportedRoutePrefix = "Error: Unsupported transport route";
|
||||||
private _requestChunkSize = 12000;
|
private _requestChunkSize = 12000;
|
||||||
|
// Keep bootstrap create/update calls on the direct extension path by default.
|
||||||
|
// Actor/bank initialization payloads are small enough for normal callExtension
|
||||||
|
// usage, and their correctness depends on preserving the native argument shape
|
||||||
|
// of [uid, json]. Transport remains available automatically for genuinely large
|
||||||
|
// requests through the chunked-request path below.
|
||||||
private _transportResponseFunctions = [
|
private _transportResponseFunctions = [
|
||||||
"actor:get",
|
"actor:get",
|
||||||
"actor:create",
|
|
||||||
"actor:update",
|
|
||||||
"actor:hot:init",
|
"actor:hot:init",
|
||||||
"actor:hot:get",
|
"actor:hot:get",
|
||||||
"actor:hot:keys",
|
"actor:hot:keys",
|
||||||
"actor:hot:save",
|
"actor:hot:save",
|
||||||
"bank:get",
|
"bank:get",
|
||||||
"bank:create",
|
|
||||||
"bank:update",
|
|
||||||
"bank:hot:init",
|
"bank:hot:init",
|
||||||
"bank:hot:get",
|
"bank:hot:get",
|
||||||
"bank:hot:save",
|
"bank:hot:save",
|
||||||
@ -127,7 +128,10 @@ private _checkRedisAvailability = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
private _buildTransportArgumentsJson = {
|
private _buildTransportArgumentsJson = {
|
||||||
params [["_rawArguments", [], [[]]]];
|
private _rawArguments = _this;
|
||||||
|
if !(_rawArguments isEqualType []) then {
|
||||||
|
_rawArguments = [_rawArguments];
|
||||||
|
};
|
||||||
|
|
||||||
private _stringArguments = _rawArguments apply {
|
private _stringArguments = _rawArguments apply {
|
||||||
if (_x isEqualType "") exitWith { _x };
|
if (_x isEqualType "") exitWith { _x };
|
||||||
@ -162,10 +166,12 @@ if (_functionLower in ["status", "version"]) exitWith {
|
|||||||
[_function, _arguments] call _callExtensionCommand
|
[_function, _arguments] call _callExtensionCommand
|
||||||
};
|
};
|
||||||
|
|
||||||
private _argumentsJson = [_arguments] call _buildTransportArgumentsJson;
|
private _argumentsJson = _arguments call _buildTransportArgumentsJson;
|
||||||
private _usesTransportResponse = _functionLower in _transportResponseFunctions;
|
private _usesTransportResponse = _functionLower in _transportResponseFunctions;
|
||||||
private _usesChunkedRequest = (count toArray _argumentsJson) > _requestChunkSize;
|
private _usesChunkedRequest = (count toArray _argumentsJson) > _requestChunkSize;
|
||||||
|
|
||||||
|
// Most calls should stay direct unless they either need chunked response
|
||||||
|
// assembly or the request body is large enough to require staging.
|
||||||
if !(_usesTransportResponse || { _usesChunkedRequest }) exitWith {
|
if !(_usesTransportResponse || { _usesChunkedRequest }) exitWith {
|
||||||
[_function, _arguments] call _callExtensionCommand
|
[_function, _arguments] call _callExtensionCommand
|
||||||
};
|
};
|
||||||
|
|||||||
@ -262,7 +262,7 @@ GVAR(OrgBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
params [["_uid", "", [""]], ["_player", objNull, [objNull]], ["_actor", createHashMap, [createHashMap]]];
|
params [["_uid", "", [""]], ["_player", objNull, [objNull]], ["_actor", createHashMap, [createHashMap]]];
|
||||||
|
|
||||||
private _memberName = _actor getOrDefault ["name", ""];
|
private _memberName = _actor getOrDefault ["name", ""];
|
||||||
if (_memberName isEqualTo "" && { _player isNotEqualTo objNull }) then {
|
if ((_memberName isEqualTo "" || { toLowerANSI _memberName isEqualTo "unknown" }) && { _player isNotEqualTo objNull }) then {
|
||||||
_memberName = name _player;
|
_memberName = name _player;
|
||||||
};
|
};
|
||||||
if (_memberName isEqualTo "") then { _memberName = "Unknown"; };
|
if (_memberName isEqualTo "") then { _memberName = "Unknown"; };
|
||||||
@ -273,7 +273,7 @@ GVAR(OrgBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
|
|
||||||
if (_uid isEqualTo "" || { _orgID isEqualTo "" }) exitWith { createHashMap };
|
if (_uid isEqualTo "" || { _orgID isEqualTo "" }) exitWith { createHashMap };
|
||||||
|
|
||||||
private _actorPatch = EGVAR(actor,ActorStore) call ["set", [_uid, "organization", _orgID, false]];
|
private _actorPatch = EGVAR(actor,ActorStore) call ["set", [_uid, "organization", _orgID, true]];
|
||||||
private _updatedActor = EGVAR(actor,ActorStore) call ["load", [_uid]];
|
private _updatedActor = EGVAR(actor,ActorStore) call ["load", [_uid]];
|
||||||
if (
|
if (
|
||||||
!(_updatedActor isEqualType createHashMap)
|
!(_updatedActor isEqualType createHashMap)
|
||||||
@ -287,7 +287,7 @@ GVAR(OrgBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
};
|
};
|
||||||
|
|
||||||
_forcedActor set ["organization", _orgID];
|
_forcedActor set ["organization", _orgID];
|
||||||
_updatedActor = EGVAR(actor,ActorStore) call ["override", [_uid, _forcedActor, false]];
|
_updatedActor = EGVAR(actor,ActorStore) call ["override", [_uid, _forcedActor, true]];
|
||||||
if (_updatedActor isEqualType createHashMap && { _updatedActor isNotEqualTo createHashMap }) then {
|
if (_updatedActor isEqualType createHashMap && { _updatedActor isNotEqualTo createHashMap }) then {
|
||||||
_actorPatch = createHashMapFromArray [["organization", _orgID]];
|
_actorPatch = createHashMapFromArray [["organization", _orgID]];
|
||||||
};
|
};
|
||||||
@ -752,12 +752,35 @@ GVAR(OrgBaseStore) = compileFinal createHashMapFromArray [
|
|||||||
["existingOrgId", _existingOrgID]
|
["existingOrgId", _existingOrgID]
|
||||||
];
|
];
|
||||||
|
|
||||||
private _envelope = _self call ["callHotOrgEnvelope", ["org:hot:register", [toJSON _context]]];
|
["org:hot:register", [toJSON _context]] call EFUNC(extension,extCall) params ["_rawResult", "_isSuccess"];
|
||||||
if (_envelope isEqualTo createHashMap) exitWith {
|
if !_isSuccess exitWith {
|
||||||
_result set ["message", "Organization registration failed."];
|
_result set ["message", "Organization service was unavailable during registration."];
|
||||||
_result
|
_result
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if !(_rawResult isEqualType "") exitWith {
|
||||||
|
_result set ["message", "Organization service returned an invalid registration response."];
|
||||||
|
_result
|
||||||
|
};
|
||||||
|
|
||||||
|
if ((_rawResult find "Error:") == 0) exitWith {
|
||||||
|
_result set ["message", _rawResult select [7]];
|
||||||
|
_result
|
||||||
|
};
|
||||||
|
|
||||||
|
private _envelope = fromJSON _rawResult;
|
||||||
|
if !(_envelope isEqualType createHashMap) exitWith {
|
||||||
|
_result set ["message", "Organization service returned malformed registration data."];
|
||||||
|
_result
|
||||||
|
};
|
||||||
|
|
||||||
|
if ("org" in _envelope) then {
|
||||||
|
private _syncedOrg = _self call ["syncHotOrg", [_envelope getOrDefault ["org", createHashMap]]];
|
||||||
|
if (_syncedOrg isNotEqualTo createHashMap) then {
|
||||||
|
_envelope set ["org", _syncedOrg];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
private _actorPatch = _self call ["applyActorOrganization", [_uid, _envelope getOrDefault ["actorOrganization", _orgID], _actor]];
|
private _actorPatch = _self call ["applyActorOrganization", [_uid, _envelope getOrDefault ["actorOrganization", _orgID], _actor]];
|
||||||
if (_actorPatch isEqualTo createHashMap) exitWith {
|
if (_actorPatch isEqualTo createHashMap) exitWith {
|
||||||
_result set ["message", "Failed to assign the player to the new organization."];
|
_result set ["message", "Failed to assign the player to the new organization."];
|
||||||
|
|||||||
@ -42,20 +42,27 @@ impl<R: ActorRepository, H: ActorHotRepository> ActorHotStateService<R, H> {
|
|||||||
return Ok(actor);
|
return Ok(actor);
|
||||||
}
|
}
|
||||||
|
|
||||||
let actor = match self.service.repository.get_by_id(&key)? {
|
let actor = self
|
||||||
Some(actor) => actor,
|
.service
|
||||||
None => {
|
.repository
|
||||||
let actor = Actor::new(key.clone()).map_err(|e| e.to_string())?;
|
.get_by_id(&key)?
|
||||||
self.service.repository.create(&actor)?;
|
.ok_or_else(|| format!("Actor with UID '{}' was not found", key))?;
|
||||||
actor
|
|
||||||
}
|
|
||||||
};
|
|
||||||
self.repository.save(&actor)?;
|
self.repository.save(&actor)?;
|
||||||
Ok(actor)
|
Ok(actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_actor(&self, key: String) -> Result<Actor, String> {
|
pub fn get_actor(&self, key: String) -> Result<Actor, String> {
|
||||||
self.init_actor(key)
|
if let Some(actor) = self.repository.get(&key)? {
|
||||||
|
return Ok(actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
let actor = self
|
||||||
|
.service
|
||||||
|
.repository
|
||||||
|
.get_by_id(&key)?
|
||||||
|
.ok_or_else(|| format!("Actor with UID '{}' was not found", key))?;
|
||||||
|
self.repository.save(&actor)?;
|
||||||
|
Ok(actor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn override_actor(&self, key: String, json_data: String) -> Result<Actor, String> {
|
pub fn override_actor(&self, key: String, json_data: String) -> Result<Actor, String> {
|
||||||
|
|||||||
@ -423,12 +423,22 @@ impl<R: OrgRepository, H: OrgHotRepository> OrgHotStateService<R, H> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut org = self.get_org(context.org_id)?;
|
let mut org = self.get_org(context.org_id)?;
|
||||||
if !org.members.contains_key(&context.member_uid) {
|
let member_name = if context.member_name.trim().is_empty() {
|
||||||
let member_name = if context.member_name.trim().is_empty() {
|
"Unknown".to_string()
|
||||||
"Unknown".to_string()
|
} else {
|
||||||
} else {
|
context.member_name
|
||||||
context.member_name
|
};
|
||||||
};
|
let should_refresh_member_name = org
|
||||||
|
.members
|
||||||
|
.get(&context.member_uid)
|
||||||
|
.map(|member| {
|
||||||
|
let existing_name = member.name.trim();
|
||||||
|
!member_name.eq_ignore_ascii_case("unknown")
|
||||||
|
&& (existing_name.is_empty() || existing_name.eq_ignore_ascii_case("unknown"))
|
||||||
|
})
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if !org.members.contains_key(&context.member_uid) || should_refresh_member_name {
|
||||||
org.members.insert(
|
org.members.insert(
|
||||||
context.member_uid.clone(),
|
context.member_uid.clone(),
|
||||||
MemberSummary {
|
MemberSummary {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user