Tutorial 10: Basic Layered Queueing Network
This example demonstrates how to model and analyze a basic layered queueing network (LQN) representing a simple client-server application with two tiers: a client layer and a database layer.
warning off;
% Example 10: Basic layered queueing network
model = LayeredNetwork('ClientDBSystem');
% Create processors
P1 = Processor(model, 'ClientHost', 1, SchedStrategy.PS);
P2 = Processor(model, 'DBHost', 1, SchedStrategy.PS);
% Create tasks
T1 = Task(model, 'ClientTask', 10, SchedStrategy.REF).on(P1);
T1.setThinkTime(Exp.fitMean(5.0)); % 5-second think time
T2 = Task(model, 'DBTask', Inf, SchedStrategy.INF).on(P2);
% Create entries
E1 = Entry(model, 'ClientEntry').on(T1);
E2 = Entry(model, 'DBEntry').on(T2);
% Define activities
A1 = Activity(model, 'ClientActivity', Exp.fitMean(1.0)).on(T1);
A1.boundTo(E1).synchCall(E2, 2.5); % 2.5 DB calls on average
A2 = Activity(model, 'DBActivity', Exp.fitMean(0.8)).on(T2);
A2.boundTo(E2).repliesTo(E2);
% Solve using LN solver with MVA
solverLN = LN(model, @(m) MVA(m));
AvgTableLN = solverLN.getAvgTable()
% Solve using LQNS solver
solverLQNS = SolverLQNS(model);
AvgTableLQNS = solverLQNS.getAvgTable()
Coming soon: Kotlin implementation for layered queueing networks is under development.
from line_solver.layered import LayeredNetwork, Processor, Task, Entry, Activity
from line_solver.constants import SchedStrategy
from line_solver.distributions import Exp
from line_solver.solvers import LN, MVA
# Create the layered network model
model = LayeredNetwork('ClientDBSystem')
# Create processors
P1 = Processor(model, 'ClientHost', 1, SchedStrategy.PS)
P2 = Processor(model, 'DBHost', 1, SchedStrategy.PS)
# Create tasks
T1 = Task(model, 'ClientTask', 10, SchedStrategy.REF).on(P1)
T1.set_think_time(Exp.fit_mean(5.0)) # 5-second think time
T2 = Task(model, 'DBTask', float('inf'), SchedStrategy.INF).on(P2)
# Create entries
E1 = Entry(model, 'ClientEntry').on(T1)
E2 = Entry(model, 'DBEntry').on(T2)
# Define activities
A1 = Activity(model, 'ClientActivity', Exp.fit_mean(1.0)).on(T1)
A1.bound_to(E1).synch_call(E2, 2.5) # 2.5 DB calls on average
A2 = Activity(model, 'DBActivity', Exp.fit_mean(0.8)).on(T2)
A2.bound_to(E2).replies_to(E2)
# Solve
solver = LN(model, lambda m: MVA(m))
avg_table = solver.avg_table()
print(avg_table)
Expected Output (LN solver with MVA)
AvgTableLN =
8x8 table
Node NodeType QLen Util RespT ResidT ArvR Tput
_________________ _________ ______ _______ ______ ______ ____ _______
ClientHost Processor NaN 0.49907 NaN NaN NaN NaN
DBHost Processor NaN 0.99823 NaN NaN NaN NaN
ClientTask RefTask 7.5 0.49907 NaN 1.7252 NaN 0.49907
DBTask Task 6.6426 0.99823 NaN 5.3235 NaN 1.2478
ClientEntry Entry 7.5 NaN 15.024 NaN NaN 0.49907
DBEntry Entry 6.6426 NaN 5.3235 NaN NaN 1.2478
ClientActivity Activity 7.5 0.49907 15.024 1.7252 NaN 0.49907
DBActivity Activity 6.6426 0.99823 5.3235 5.3235 NaN 1.2478
Expected Output (LQNS solver)
AvgTableLQNS =
8x8 table
Node NodeType QLen Util RespT ResidT ArvR Tput
_________________ _________ ______ _______ ______ ______ ____ _______
ClientHost Processor NaN 0.49696 NaN NaN NaN NaN
DBHost Processor NaN 0.99392 NaN NaN NaN NaN
ClientTask RefTask 7.5152 0.49696 NaN NaN 0 0.49696
DBTask Task 6.6626 0.99392 NaN NaN 0 1.2424
ClientEntry Entry 7.5152 0.49696 15.122 NaN 0 0.49696
DBEntry Entry 6.6626 0.99392 5.3627 NaN 0 1.2424
ClientActivity Activity 7.5152 0.49696 15.122 NaN 0 0.49696
DBActivity Activity 6.6626 0.99392 5.3627 NaN 0 1.2424