Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
E
erlang
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
erlang
Commits
a28cb437
Unverified
Commit
a28cb437
authored
Oct 15, 2018
by
Сергей Прохоров
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add "status" for dc pools; add initial burst handling for pool growth
parent
a8803a7b
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
58 additions
and
22 deletions
+58
-22
README.md
README.md
+2
-0
mtp_config.erl
src/mtp_config.erl
+11
-1
mtp_dc_pool.erl
src/mtp_dc_pool.erl
+44
-21
mtp_down_conn_sup.erl
src/mtp_down_conn_sup.erl
+1
-0
No files found.
README.md
View file @
a28cb437
...
@@ -14,6 +14,8 @@ Features
...
@@ -14,6 +14,8 @@ Features
*
Automatic configuration reload (no need for restarts once per day)
*
Automatic configuration reload (no need for restarts once per day)
*
Most of the configuration options can be updated without service restart
*
Most of the configuration options can be updated without service restart
*
Very high performance - can handle tens of thousands connections! Scales to all CPU cores.
*
Very high performance - can handle tens of thousands connections! Scales to all CPU cores.
*
Supports multiplexing (Many connections Client -> Proxy are wrapped to small amount of
connections Proxy -> Telegram Server)
*
Small codebase compared to official one
*
Small codebase compared to official one
*
A lots of metrics could be exported (optional)
*
A lots of metrics could be exported (optional)
...
...
src/mtp_config.erl
View file @
a28cb437
...
@@ -19,7 +19,8 @@
...
@@ -19,7 +19,8 @@
get_downstream_pool
/
1
,
get_downstream_pool
/
1
,
get_netloc
/
1
,
get_netloc
/
1
,
get_netloc_safe
/
1
,
get_netloc_safe
/
1
,
get_secret
/
0
]).
get_secret
/
0
,
status
/
0
]).
-
export
([
register_name
/
2
,
-
export
([
register_name
/
2
,
unregister_name
/
1
,
unregister_name
/
1
,
whereis_name
/
1
,
whereis_name
/
1
,
...
@@ -131,6 +132,15 @@ get_secret() ->
...
@@ -131,6 +132,15 @@ get_secret() ->
[{_,
Key
}]
=
ets
:
lookup
(
?
TAB
,
key
),
[{_,
Key
}]
=
ets
:
lookup
(
?
TAB
,
key
),
Key
.
Key
.
status
()
->
[{
?
IDS_KEY
,
L
}]
=
ets
:
lookup
(
?
TAB
,
?
IDS_KEY
),
lists
:
map
(
fun
(
DcId
)
->
DcPoolStatus
=
mtp_dc_pool
:
status
(
whereis_name
(
DcId
)),
DcPoolStatus
#
{
dc_id
=>
DcId
}
end
,
L
).
%%%===================================================================
%%%===================================================================
%%% gen_server callbacks
%%% gen_server callbacks
%%%===================================================================
%%%===================================================================
...
...
src/mtp_dc_pool.erl
View file @
a28cb437
...
@@ -18,7 +18,8 @@
...
@@ -18,7 +18,8 @@
get
/
3
,
get
/
3
,
return
/
2
,
return
/
2
,
add_connection
/
1
,
add_connection
/
1
,
ack_connected
/
2
]).
ack_connected
/
2
,
status
/
1
]).
%% gen_server callbacks
%% gen_server callbacks
-
export
([
init
/
1
,
handle_call
/
3
,
handle_cast
/
2
,
handle_info
/
2
,
-
export
([
init
/
1
,
handle_call
/
3
,
handle_cast
/
2
,
handle_info
/
2
,
...
@@ -26,6 +27,7 @@
...
@@ -26,6 +27,7 @@
-
define
(
SERVER
,
?
MODULE
).
-
define
(
SERVER
,
?
MODULE
).
-
define
(
APP
,
mtproto_proxy
).
-
define
(
APP
,
mtproto_proxy
).
-
define
(
BURST_MAX
,
10
).
-
type
upstream
()
::
mtp_handler
:
handle
().
-
type
upstream
()
::
mtp_handler
:
handle
().
-
type
downstream
()
::
mtp_down_conn
:
handle
().
-
type
downstream
()
::
mtp_down_conn
:
handle
().
...
@@ -56,6 +58,9 @@ add_connection(Pool) ->
...
@@ -56,6 +58,9 @@ add_connection(Pool) ->
ack_connected
(
Pool
,
Downstream
)
->
ack_connected
(
Pool
,
Downstream
)
->
gen_server
:
cast
(
Pool
,
{
connected
,
Downstream
}).
gen_server
:
cast
(
Pool
,
{
connected
,
Downstream
}).
status
(
Pool
)
->
gen_server
:
call
(
Pool
,
status
).
%%%===================================================================
%%%===================================================================
%%% gen_server callbacks
%%% gen_server callbacks
%%%===================================================================
%%%===================================================================
...
@@ -71,7 +76,18 @@ handle_call({get, Upstream, Opts}, _From, State) ->
...
@@ -71,7 +76,18 @@ handle_call({get, Upstream, Opts}, _From, State) ->
{
reply
,
Downstream
,
State1
};
{
reply
,
Downstream
,
State1
};
handle_call
(
add_connection
,
_
From
,
State
)
->
handle_call
(
add_connection
,
_
From
,
State
)
->
State1
=
connect
(
State
),
State1
=
connect
(
State
),
{
reply
,
ok
,
State1
}.
{
reply
,
ok
,
State1
};
handle_call
(
status
,
_
From
,
#state
{
downstreams
=
Ds
,
upstreams
=
Us
}
=
State
)
->
{
NDowns
,
NUps
,
Min
,
Max
}
=
ds_fold
(
fun
(_
Pid
,
N
,
{
NDowns
,
NUps
,
Min
,
Max
})
->
{
NDowns
+
1
,
NUps
+
N
,
min
(
Min
,
N
),
max
(
Max
,
N
)}
end
,
{
0
,
0
,
map_size
(
Us
),
0
},
Ds
),
{
reply
,
#
{
n_downstreams
=>
NDowns
,
n_upstreams
=>
NUps
,
min
=>
Min
,
max
=>
Max
},
State
}.
handle_cast
({
return
,
Upstream
},
State
)
->
handle_cast
({
return
,
Upstream
},
State
)
->
{
noreply
,
handle_return
(
Upstream
,
State
)};
{
noreply
,
handle_return
(
Upstream
,
State
)};
...
@@ -82,10 +98,10 @@ handle_info({'DOWN', MonitorRef, process, Pid, _Reason}, State) ->
...
@@ -82,10 +98,10 @@ handle_info({'DOWN', MonitorRef, process, Pid, _Reason}, State) ->
%% TODO: monitor downstream connections as well
%% TODO: monitor downstream connections as well
{
noreply
,
handle_down
(
MonitorRef
,
Pid
,
State
)}.
{
noreply
,
handle_down
(
MonitorRef
,
Pid
,
State
)}.
terminate
(_
Reason
,
#state
{
downstreams
=
Ds
})
->
terminate
(_
Reason
,
#state
{
downstreams
=
Ds
})
->
ds_fo
reach
(
ds_fo
ld
(
fun
(
Pid
)
->
fun
(
Pid
,
_,
_
)
->
mtp_down_conn
:
shutdown
(
Pid
)
mtp_down_conn
:
shutdown
(
Pid
)
end
,
Ds
),
end
,
ok
,
Ds
),
%% upstreams will be killed by connection itself
%% upstreams will be killed by connection itself
ok
.
ok
.
code_change
(_
OldVsn
,
State
,
_
Extra
)
->
code_change
(_
OldVsn
,
State
,
_
Extra
)
->
...
@@ -139,17 +155,23 @@ handle_down(MonRef, MaybeUpstream, #state{downstreams = Ds,
...
@@ -139,17 +155,23 @@ handle_down(MonRef, MaybeUpstream, #state{downstreams = Ds,
maybe_spawn_connection
(
CurrentMin
,
#state
{
pending_downstreams
=
Pending
}
=
St
)
->
maybe_spawn_connection
(
CurrentMin
,
#state
{
pending_downstreams
=
Pending
}
=
St
)
->
%% TODO: shrinking (by timer)
%% TODO: shrinking (by timer)
case
application
:
get_env
(
?
APP
,
clients_per_dc_connection
)
of
ToSpawn
=
{
ok
,
N
}
when
CurrentMin
>
N
,
case
application
:
get_env
(
?
APP
,
clients_per_dc_connection
)
of
Pending
==
[]
->
{
ok
,
N
}
when
CurrentMin
>
N
,
ToSpawn
=
2
,
Pending
==
[]
->
lists
:
foldl
(
2
;
fun
(_,
S
)
->
{
ok
,
N
}
when
CurrentMin
>
(
N
*
1
.
5
),
connect
(
S
)
length
(
Pending
)
<
?
BURST_MAX
->
end
,
St
,
lists
:
seq
(
1
,
ToSpawn
));
%% To survive initial bursts
_
->
?
BURST_MAX
-
length
(
Pending
);
St
_
->
end
.
0
end
,
lists
:
foldl
(
fun
(_,
S
)
->
connect
(
S
)
end
,
St
,
lists
:
seq
(
1
,
ToSpawn
)).
%% Initiate new async connection
%% Initiate new async connection
connect
(
#state
{
pending_downstreams
=
Pending
,
connect
(
#state
{
pending_downstreams
=
Pending
,
...
@@ -181,12 +203,13 @@ ds_new(Connections) ->
...
@@ -181,12 +203,13 @@ ds_new(Connections) ->
pid_psq
:
add
(
Conn
,
Psq1
)
pid_psq
:
add
(
Conn
,
Psq1
)
end
,
Psq
,
Connections
).
end
,
Psq
,
Connections
).
-
spec
ds_foreach
(
fun
(
(
downstream
())
->
any
()
),
ds_store
())
->
ok
.
-
spec
ds_fold
(
fun
(
(
downstream
(),
integer
(),
Acc
)
->
Acc
),
Acc
,
ds_store
())
->
Acc
when
ds_foreach
(
Fun
,
St
)
->
Acc
::
any
().
ds_fold
(
Fun
,
Acc0
,
St
)
->
psq
:
fold
(
psq
:
fold
(
fun
(_,
_
N
,
Pid
,
_
)
->
fun
(_,
N
,
Pid
,
Acc
)
->
Fun
(
Pid
)
Fun
(
Pid
,
N
,
Acc
)
end
,
ok
,
St
).
end
,
Acc0
,
St
).
%% Add new downstream to storage
%% Add new downstream to storage
-
spec
ds_add_downstream
(
downstream
(),
ds_store
())
->
ds_store
().
-
spec
ds_add_downstream
(
downstream
(),
ds_store
())
->
ds_store
().
...
...
src/mtp_down_conn_sup.erl
View file @
a28cb437
...
@@ -4,6 +4,7 @@
...
@@ -4,6 +4,7 @@
%%% @doc
%%% @doc
%%% Supervisor for mtp_down_conn processes
%%% Supervisor for mtp_down_conn processes
%%% @end
%%% @end
%%% TODO: maybe have one supervisor per-DC
%%% Created : 14 Oct 2018 by Sergey <me@seriyps.ru>
%%% Created : 14 Oct 2018 by Sergey <me@seriyps.ru>
%%%-------------------------------------------------------------------
%%%-------------------------------------------------------------------
-
module
(
mtp_down_conn_sup
).
-
module
(
mtp_down_conn_sup
).
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment