% TaskRunner - simple parallel.cluster.CJSCluster subclass to support job execution.

% Copyright 2011-2019 The MathWorks, Inc.

classdef ( ConstructOnLoad = true, Sealed ) TaskRunner < parallel.cluster.CJSCluster
    properties ( SetAccess = immutable )
        Host
    end

    methods ( Hidden )
        function hDestroyJob( ~, ~ )
        end
        function hDestroyTask( ~, ~ )
        end
        function ok = hCancelJob( ~, ~ )
            warning(message('parallel:cluster:TaskRunnerCancellation'));
            ok = false;
        end
        function ok = hCancelTask( ~, ~ )
            warning(message('parallel:cluster:TaskRunnerCancellation'));
            ok = false;
        end
        function hSubmitIndependentJob( varargin )
            error(message('parallel:cluster:TaskRunnerSubmission'));
        end
        function hSubmitCommunicatingJob( varargin )
            error(message('parallel:cluster:TaskRunnerSubmission'));
        end
        function hSetProperty( obj, names, values )
            if ~iscell( names )
                names = { names };
                values = { values };
            end
            for ii = 1:length( names )
                if isequal( names{ii}, 'OperatingSystem' )
                    throwAsCaller( obj.buildCannotModify( 'OperatingSystem' ) );
                end
                obj.hSetProperty@parallel.cluster.CJSCluster(names{ii}, values{ii});
            end
        end
        function [clusterPropertyMap, propNames] = hGetDisplayItems(obj, diFactory)
            clusterPropertyMap = hGetDisplayItems@parallel.Cluster(obj, diFactory);
            propNames = {'Host', 'JobStorageLocation'};            
        end
    end

    methods
        function obj = TaskRunner( varargin )

            import parallel.internal.cluster.ConstructorArgsHelper
            import parallel.cluster.CJSCluster

            if ( nargin == 1 ) && isa( varargin{1}, 'parallel.internal.cluster.AbstractStorage' )
                
                storage = varargin{1};
               
                cProf = '';
                % Should have no impact on the Worker anyway so let it be default
                storageLocValType = parallel.internal.settings.ValueType.Factory; 
                
                dataLoc = [];
            else
                try
                    [propsFromArgs, cProf] = ...
                        ConstructorArgsHelper.interpretClusterCtorArgs( ...
                            ?parallel.cluster.TaskRunner, varargin{:} );
                catch E
                    throw( E );
                end
                
                [dataLoc, storageLocValType] = CJSCluster.chooseDataLocation( propsFromArgs );
                
                storage = parallel.internal.cluster.FileStorage.createFileStorage( dataLoc );
            end

            obj@parallel.cluster.CJSCluster( 'TaskRunner', cProf, storage, storageLocValType, dataLoc );
            
            obj.Host = parallel.internal.general.HostNameUtils.getLocalCanonicalHostName();
        end
    end
    methods ( Hidden, Access = protected )
        function jobState = getJobState( ~, ~, jobState )
        end
        function tf = wasSubmittedByThisType( ~, ~ )
            tf = false;
        end
        function [names, values] = getClusterSpecificEnvVars( ~ )
            names  = {};
            values = {};
        end
    end
    
    methods ( Access = protected )
        % Get all the properties needed for the ClusterMemento.
        function props = getAllMementoProperties( ~, ~ )
            props = "JobStorageLocation";
        end
    end
    
    methods ( Access = private )
        function delete( obj )
            delete@handle( obj );
        end
    end
end
%#ok<*ATUNK>
