-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpaper.latex
127 lines (113 loc) · 8.51 KB
/
paper.latex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
\documentclass[14pt]{extarticle}
\usepackage{amsmath}
\usepackage[russian]{babel}
\usepackage[left=15mm,right=15mm,top=20mm,bottom=20mm]{geometry}
\title{Проекта Предиктивное уведомление клиентов boost::beast}
\date{2019-12-11}
\author{Мельников Лев Александрович СКБ 161}
\begin{document}
\maketitle
\section{Используемые понятия}
\begin{itemize}
\item Уведомление клиентов - мероприятие в котором, ограниченное число операторов
совершают звонки большому числу клиентов
\item Метод уведомления клиентов - набор правил, согласно которым определяется стратегия
уведомления клиентов
\item Прогрессивный метод уведомления клиентов - метод, по которому новый звонок
совершается, только если количество свободных операторов больше чем
количество вызовов, ожидающих ответа клиента
\item Брошенный вызов - звонок, который был принят клиентом, но не был
отвечен оператором
\item Предиктивный метод уведомления клиентов - метод согласно, которому новые звонки
могут совершаться, даже если свободных операторов меньше чем вызовов,
ожидающих ответа. Предиктивные методы с помощью предсказаний минимизируют
количество
брошенных вызовов
\item АТС - Автоматическая телефонная станция
\item ВАТС - Виртуальная АТС
\end{itemize}
\section{Постановка задачи}
Разработать программу для управления уведомлением клиентов по прогрессивному методу.
Программа должна работать по протоколоу http и поддерживать следующие методы.
\begin{itemize}
\item begin - создать сессию обзвона. Параметр session - название сессии.
Дополнительный параметр stat\_size -
размер статистики, которую будет принимать эта сессия.
\item end - удалить сессию. Параметр session - название сессии.
\item add - добавить в статистику сессии вызов. Параметр session - название
сессии. setup - время до поднятия трубки. talk - время разговора.
\item get - Получить количество вызовов, которое нужно совершить
для максимальной эффективности. Параметр session - название сессии.
free - количество свободных операторов. incoming - количество вызовов,
которые еще не приняты.
\end{itemize}
Реализация должна в методе get содержать механизм для рассчета по прогрессивному методу,
но быть легко расширяемой на предиктивный метод. Реализация также должна
иметь возможность обрабатывать несколько сессий одновременно.
\section{Обзор технологии}
В реализации используется boost::asio и boost::beast::http. boost::asio
используется для многопоточной ассинхронной обработки запросов.
Функция accept принимает соединение(здесь и далее асинхронно)
и в обработчике новго соединения создает объект
класса worker, выделяя его в динамическую память. После этого обработчик заново
вызвает функцию accept. Таким образом достигается непрерывное и ассинхронное
принятие соединений. Объект класса worker - в конструкторе создает shared\_ptr,
ссылающийся на себя. И далее начинает обрабатывать соединение. Полученные
данные передаются для обработки в объект класса session\_manager - в котором,
реализована логика обзвона. После того как запрос обработан и ответ отправлен
(а также в случае ошибки и невозможности обработать запрос),
shared\_ptr зануляется, что приводит к освобождению памяти выделенной под
worker.
\section{Использование boost::beast}
Из boost::beast::http используются parser и request(response). В parser делегируется
работа по обработке http запроса, он передается
в качестве аргумента в функцию async\_read. request(response) используются для
чтения(составления) запроса(ответа) в удобном виде.
\section{Трудности в разработке}
Узким местом в производительности являются блокировки общих данных,
а особенно блокировки в методе get, тк он может требовать времени сильно больше
чем вся остальная часть программы. Было предложено следующее решение. В реализации
есть хранилище сессий и его мьютекс - storage\_lock. У каждой сессии есть свой
мьютекс. Порядок захвата мьютексов определен следующим образом:
\begin{enumerate}
\item begin
\begin{enumerate}
\item master(lock)
\item Добавление сессии в storage(Быстрая операция)
\item master(unlock)
\end{enumerate}
\item add
\begin{enumerate}
\item master(lock)
\item Поиск нужной сессии(Быстрая операция)
\item session(lock)
\item master(unlock)
\item Добавление статистики(Быстрая операция)
\item session(unlock)
\end{enumerate}
\item get
\begin{enumerate}
\item master(lock)
\item Поиск нужной сессии(Быстрая операция)
\item session(lock)
\item master(unlock)
\item Предиктивный метод(Медленная операция операция)
\item session(unlock)
\end{enumerate}
\item end
\begin{enumerate}
\item master(lock)
\item Поиск нужной сессии(Быстрая операция)
\item session(lock)
\item session(unlock)
\item Удаление сесси(Быстрая операция)
\item master(unlock)
\end{enumerate}
\end{enumerate}
Блокировке 4(c) - 4(d) нужны, чтобы убедиться, что мьютексом сессии никто не
владеет. Так как порядок захвата мьютексов одинаковый - deadlock невозможен.
\section{Материалы}
Ссылка на репозиторий: https://github.com/markgrin/pdc\_daemon
. В коде также присутствует документация, которая не приведена здесь. Также
в репозитории есть файл test.py для тестирования работоспособности программы.
\end{document}