LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
JobClass.m
1classdef JobClass < NetworkElement
2 % An abstract class for a collection of indistinguishable jobs
3 %
4 % Copyright (c) 2012-2026, Imperial College London
5 % All rights reserved.
6
7 properties
8 priority;
9 deadline; % relative deadline from arrival (Inf = no deadline)
10 refstat; % reference station
11 isrefclass; % is this a reference class within a chain?
12 index; % node index
13 type;
14 completes; % true if passage through reference station is a completion
15 replySignalClass; % Signal class that will unblock servers waiting for reply (for synchronous call semantics)
16 patience; % Global patience distribution for this class (customers abandon queues after patience time)
17 patienceType; % Global patience type for this class (PatienceType.RENEGING or PatienceType.BALKING)
18 end
19
20 methods (Hidden)
21 %Constructor
22 function self = JobClass(type, name)
23 % SELF = JOBCLASS(TYPE, NAME)
24
25 self@NetworkElement(name);
26 self.priority = 0;
27 self.deadline = Inf;
28 self.refstat = Node('Unallocated');
29 self.isrefclass = false;
30 self.index = 1;
31 self.type=type;
32 self.completes = true;
33 self.replySignalClass = [];
34 self.patience = [];
35 self.patienceType = [];
36 end
37
38 function self = setReferenceStation(self, source)
39 % SELF = SETREFERENCESTATION(SOURCE)
40
41 self.refstat = source;
42 end
43
44 function self = setReferenceClass(self, bool)
45 % SELF = SETREFERENCECLASS(BOOL)
46 self.isrefclass = bool;
47 end
48
49 function boolIsa = isReferenceStation(self, node)
50 % BOOLISA = ISREFERENCESTATION(NODE)
51
52 boolIsa = strcmp(self.refstat.name,node.name);
53 end
54
55 function boolIsa = isReferenceClass(self)
56 % BOOLISA = ISREFERENCECLASS()
57
58 boolIsa = self.isrefclass;
59 end
60
61 % function self = set.priority(self, priority)
62 % SELF = SET.PRIORITY(PRIORITY)
63
64 % if ~(rem(priority,1) == 0 && priority >= 0)
65 % line_error(mfilename,'Priority must be an integer.\n');
66 % end
67 % self.priority = priority;
68 % end
69 end
70
71 methods (Access=public)
72 function ind = subsindex(self)
73 % IND = SUBSINDEX()
74
75 ind = double(self.index)-1; % 0 based
76 end
77
78 function summary(self)
79 % SUMMARY()
80 line_printf('Class (%s): <strong>%s</strong>',self.type,self.getName);
81 end
82
83 function self = setReplySignalClass(self, replyClass)
84 % SETREPLYSIGNALCLASS Set the Signal class for synchronous call reply
85 %
86 % self = SETREPLYSIGNALCLASS(self, replyClass) configures this job
87 % class to expect a reply signal from the specified Signal class.
88 % When a job of this class completes service, the server will block
89 % until receiving a REPLY signal from the specified class.
90 %
91 % This implements LQN-style synchronous call semantics where a
92 % client sends a request, blocks waiting for a reply, and then
93 % continues processing after the reply arrives.
94 %
95 % @param replyClass Signal object with SignalType.REPLY that will unblock the server
96 % @return self The modified JobClass instance
97
98 if ~isa(replyClass, 'Signal')
99 line_error(mfilename, 'Reply class must be a Signal.');
100 end
101 if replyClass.signalType ~= SignalType.REPLY
102 line_error(mfilename, 'Reply class must have SignalType.REPLY.');
103 end
104 self.replySignalClass = replyClass;
105 end
106
107 function idx = getReplySignalClassIndex(self)
108 % GETREPLYSIGNALCLASSINDEX Get the index of the reply signal class
109 %
110 % idx = GETREPLYSIGNALCLASSINDEX(self) returns the index of the
111 % Signal class that will unblock servers waiting for this class,
112 % or -1 if no reply is expected.
113 %
114 % @return idx Index of reply signal class, or -1 if none
115
116 if isempty(self.replySignalClass)
117 idx = -1;
118 else
119 idx = self.replySignalClass.index;
120 end
121 end
122
123 function tf = expectsReply(self)
124 % EXPECTSREPLY Check if this class expects a reply signal
125 %
126 % tf = EXPECTSREPLY(self) returns true if this class has been
127 % configured to expect a reply signal (via setReplySignalClass).
128 %
129 % @return tf True if a reply signal is expected
130
131 tf = ~isempty(self.replySignalClass);
132 end
133
134 function self = setPatience(self, varargin)
135 % SELF = SETPATIENCE(DISTRIBUTION) - Backwards compatible
136 % SELF = SETPATIENCE(PATIENCETYPE, DISTRIBUTION) - Explicit type
137 %
138 % Sets the global patience type and distribution for this job class.
139 % This applies to all queues unless overridden by queue-specific settings.
140 %
141 % Parameters:
142 % patienceType - (Optional) PatienceType constant (RENEGING or BALKING)
143 % If omitted, defaults to PatienceType.RENEGING
144 % distribution - Any LINE distribution (Exp, Erlang, HyperExp, etc.)
145 % excluding modulated processes (BMAP, MAP, MMPP2)
146 %
147 % Examples:
148 % jobclass.setPatience(Exp(0.1)) % Defaults to RENEGING
149 % jobclass.setPatience(PatienceType.RENEGING, Exp(0.1))
150 % jobclass.setPatience(PatienceType.BALKING, Det(5.0))
151
152 % Handle backwards compatibility: 1 or 2 arguments
153 if length(varargin) == 1
154 % Old signature: setPatience(distribution)
155 distribution = varargin{1};
156 patienceType = PatienceType.RENEGING; % Default to RENEGING
157 elseif length(varargin) == 2
158 % New signature: setPatience(patienceType, distribution)
159 patienceType = varargin{1};
160 distribution = varargin{2};
161 else
162 line_error(mfilename, 'Invalid number of arguments. Use setPatience(distribution) or setPatience(patienceType, distribution)');
163 end
164
165 if isa(distribution, 'BMAP') || isa(distribution, 'MAP') || isa(distribution, 'MMPP2')
166 line_error(mfilename, 'Modulated processes (BMAP, MAP, MMPP2) are not supported for patience distributions.');
167 end
168
169 % Validate patience type
170 if patienceType ~= PatienceType.RENEGING && patienceType ~= PatienceType.BALKING
171 line_error(mfilename, 'Invalid patience type. Use PatienceType.RENEGING or PatienceType.BALKING.');
172 end
173
174 % Only RENEGING is currently supported
175 if patienceType == PatienceType.BALKING
176 line_error(mfilename, 'BALKING patience type is not yet supported. Use PatienceType.RENEGING.');
177 end
178
179 if isempty(self.obj)
180 self.patience = distribution;
181 self.patienceType = patienceType;
182 else
183 self.obj.setPatience(patienceType, distribution.obj);
184 end
185 end
186
187 function distribution = getPatience(self)
188 % DISTRIBUTION = GETPATIENCE()
189 %
190 % Returns the global patience distribution for this job class.
191 %
192 % Returns:
193 % distribution - The patience distribution, or [] if not set
194
195 if isempty(self.obj)
196 if ~isempty(self.patience)
197 distribution = self.patience;
198 else
199 distribution = [];
200 end
201 else
202 distObj = self.obj.getPatience();
203 if isempty(distObj)
204 distribution = [];
205 else
206 % Convert Java object to MATLAB Distribution
207 distribution = Distribution.fromJavaObject(distObj);
208 end
209 end
210 end
211
212 function patienceType = getPatienceType(self)
213 % PATIENCETYPE = GETPATIENCETYPE()
214 %
215 % Returns the global patience type for this job class.
216 %
217 % Returns:
218 % patienceType - The patience type (PatienceType constant), or [] if not set
219
220 if isempty(self.obj)
221 if ~isempty(self.patienceType)
222 patienceType = self.patienceType;
223 else
224 patienceType = [];
225 end
226 else
227 patienceTypeObj = self.obj.getPatienceType();
228 if isempty(patienceTypeObj)
229 patienceType = [];
230 else
231 patienceType = PatienceType.fromId(patienceTypeObj.getID());
232 end
233 end
234 end
235
236 function tf = hasPatience(self)
237 % TF = HASPATIENCE()
238 %
239 % Returns true if this class has a patience distribution set.
240
241 dist = self.getPatience();
242 tf = ~isempty(dist) && ~isa(dist, 'Disabled');
243 end
244 end
245
246end