Download

How to handle simultaneous local calls to an online subsystem?

What should happen when you issue simultaneous calls to a subsystem (coming from the same user), when working with latent requests?

I mean, the interface uses a delegate in which you usually add a function reference to be called and then you broadcast it when finished. But what if there’s multiple functions subscribed to that delegate?

I’m trying to accept multiple calls, but the broadcast calls all of them when the first request finishes. If I could call only the first subscriber it should work, but I can’t change the subsystem interface (working with Facebook).

Should I drop incoming requests if the subsystem is busy? If not, how should I deal with the delegate?

Thanks!

I guess you have to describe a little more your problem and possibly discuss in a Facebook SDK group about it as it does not seem to be UE specific.

Well, it is UE4 specific. To be more specific, the online subsystem sharing interface declares a delegate as such:

[OnlineSharingInterface.h]


	/**
	 * Called when we have successfully/failed to post a status update to the server
	 *
	 *   @param LocalUserNum		- The controller number of the associated user
	 *   @param bWasSuccessful	- True if a post was successfully added to the server
	 */
	DEFINE_ONLINE_PLAYER_DELEGATE_ONE_PARAM(MAX_LOCAL_PLAYERS, OnSharePostComplete, bool);

It is a macro:

[OnlineDelegateMacros.h]

[Base]


#define DEFINE_ONLINE_PLAYER_DELEGATE_BASE(MaxPlayers, DelegateName) \
public: \
	F##DelegateName DelegateName##Delegates[MaxPlayers]; \
public: \
	virtual FDelegateHandle Add##DelegateName##Delegate_Handle(int32 LocalUserNum, const F##DelegateName##Delegate& Delegate) \
	{ \
		FDelegateHandle Result; \
		if (LocalUserNum >= 0 && LocalUserNum < MaxPlayers) \
		{ \
			Result = DelegateName##Delegates[LocalUserNum].Add(Delegate); \
		} \
		return Result; \
	} \
	virtual void Clear##DelegateName##Delegate_Handle(int32 LocalUserNum, FDelegateHandle& Handle) \
	{ \
		if (LocalUserNum >= 0 && LocalUserNum < MaxPlayers) \
		{ \
			DelegateName##Delegates[LocalUserNum].Remove(Handle); \
			Handle.Reset(); \
		} \
	}

[OneParam]


#define DEFINE_ONLINE_PLAYER_DELEGATE_ONE_PARAM(MaxPlayers, DelegateName, Param1Type) \
	DEFINE_ONLINE_PLAYER_DELEGATE_BASE(MaxPlayers, DelegateName) \
	virtual void Trigger##DelegateName##Delegates(int32 LocalUserNum, Param1Type Param1) \
	{ \
		if (LocalUserNum >= 0 && LocalUserNum < MaxPlayers) \
		{ \
			DelegateName##Delegates[LocalUserNum].Broadcast(LocalUserNum, Param1); \
		} \
	}

I actually implement this interface. When I’m finished sharing, I trigger the delegate:


		TriggerOnSharePostCompleteDelegates(LocalUserNum, *true/false*);

In order to use it, I bind to the delegate and call the interface defined method:



		SharingCompleteDelegateHandle = FBSubSystem->GetSharingInterface()->OnSharePostCompleteDelegates->AddUObject(this, &USharingCallbackProxy::OnStatusUpdateComplete);
		FBSubSystem->GetSharingInterface()->ShareStatusUpdate(0, StatusUpdate);

It works fine. The problem is that the sharing is actually a HTTP request, which is latent. When I call it the first time, it binds to the delegate and issue a request. If while the request is processing comes a second request, It will add to the same delegate. When the first request finishes, it broadcasts, firing both delegates (but the second request didn’t even finished processing). The problem here is just the delegate.

I’m wondering how should I handle this. How was the interface designed to handle something like this? Should I change some logic I’m using?

Thanks!

Looking at the interface for IOnlineSharing there is no notion of multiplexing (like a request id etc). So either it needs to be used sequentially (one request at a time), or you need to use distinct instances of IOnlineSharing implementations for each request. In the later case you must not use FBSubSystem->GetSharingInterface() but allocate one sharing interface per request. However the engine implementation of IOnlineSharing may not support this. You can try and see :slight_smile: