function [OK, out] = remoteBlockExecutionSerDeser(action, varargin)
%remoteBlockExecution - this function controls the SPMD block execution on the labs
% All arguments and results are serialized

% Copyright 2021 The MathWorks, Inc.

% Delegate to remoteBlockExecutionPlain. This function just does any
% required adaption of arguments and results.

switch action
    case 'prelude'
        [commHCell, fcnHandles, keysToClear, preludeExcept] = iUnpackPreludeArgs(varargin{:});
        [OK, out] = spmdlang.remoteBlockExecutionPlain(action, commHCell, fcnHandles, keysToClear, preludeExcept);
    otherwise
        [OK, out] = spmdlang.remoteBlockExecutionPlain(action, varargin{:});
end
try
    out = parallel.internal.pool.optionallySerialize(out);
catch E
    OK = false;
    stackFilesToIgnore = {'LocalSpmdExecutor', 'remoteBlockExecution'};
    out = parallel.internal.pool.optionallySerialize(ParallelException.hBuildFromRemoteException(E, stackFilesToIgnore));
end
    
end

function [commHCell, fcnHandles, keysToClear, preludeExcept] = iUnpackPreludeArgs(serCommHandleCell, serializedFcnHandles, keysToClearIn)

E = [];
commHCell = [];
fcnHandles = [];

try
    commHCell = parallel.internal.pool.optionallyDeserialize(serCommHandleCell);
    fcnHandles = parallel.internal.pool.optionallyDeserialize(serializedFcnHandles);
catch E
end

preludeExcept = E;

keysToClear = keysToClearIn;


end
