Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
mtproto_proxy
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
mtproto_proxy
Commits
91b89061
Unverified
Commit
91b89061
authored
Oct 18, 2018
by
Сергей Прохоров
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add monitor dc_pool <-> down_conn
parent
15bff248
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
72 additions
and
30 deletions
+72
-30
mtp_dc_pool.erl
src/mtp_dc_pool.erl
+54
-19
mtp_down_conn.erl
src/mtp_down_conn.erl
+18
-11
No files found.
src/mtp_dc_pool.erl
View file @
91b89061
...
@@ -35,9 +35,15 @@
...
@@ -35,9 +35,15 @@
-
record
(
state
,
-
record
(
state
,
{
dc_id
::
mtp_config
:
dc_id
(),
{
dc_id
::
mtp_config
:
dc_id
(),
%% This one might be really big:
upstreams
=
#
{}
::
#
{
upstream
()
=>
downstream
()},
upstreams
=
#
{}
::
#
{
upstream
()
=>
downstream
()},
%% On-demand downstreams are started asynchronously;
pending_downstreams
=
[]
::
[
pid
()],
pending_downstreams
=
[]
::
[
pid
()],
downstreams
::
ds_store
()
%% Downstream storage that allows to choose the one with minimal
%% number of connections
%% Should be relatively small
downstreams
::
ds_store
(),
downstream_monitors
=
#
{}
::
#
{
reference
()
=>
downstream
()}
}).
}).
%%%===================================================================
%%%===================================================================
...
@@ -66,10 +72,11 @@ status(Pool) ->
...
@@ -66,10 +72,11 @@ status(Pool) ->
%%%===================================================================
%%%===================================================================
init
(
DcId
)
->
init
(
DcId
)
->
InitConnections
=
application
:
get_env
(
mtproto_proxy
,
init_dc_connections
,
4
),
InitConnections
=
application
:
get_env
(
mtproto_proxy
,
init_dc_connections
,
4
),
PendingConnections
=
[
do_connect
(
DcId
)
||
_
<-
lists
:
seq
(
1
,
InitConnections
)],
State
=
#state
{
dc_id
=
DcId
,
Connections
=
recv_pending
(
PendingConnections
),
downstreams
=
ds_new
([])},
Downstreams
=
ds_new
(
Connections
),
State1
=
connect_many
(
InitConnections
,
State
),
{
ok
,
#state
{
dc_id
=
DcId
,
downstreams
=
Downstreams
}}.
State2
=
wait_pending
(
State1
),
{
ok
,
State2
}.
handle_call
({
get
,
Upstream
,
Opts
},
_
From
,
State
)
->
handle_call
({
get
,
Upstream
,
Opts
},
_
From
,
State
)
->
{
Downstream
,
State1
}
=
handle_get
(
Upstream
,
Opts
,
State
),
{
Downstream
,
State1
}
=
handle_get
(
Upstream
,
Opts
,
State
),
...
@@ -140,17 +147,30 @@ handle_return(Upstream, #state{downstreams = Ds,
...
@@ -140,17 +147,30 @@ handle_return(Upstream, #state{downstreams = Ds,
St
#state
{
downstreams
=
Ds1
,
St
#state
{
downstreams
=
Ds1
,
upstreams
=
Us1
}.
upstreams
=
Us1
}.
handle_down
(
MonRef
,
MaybeUpstream
,
#state
{
downstreams
=
Ds
,
handle_down
(
MonRef
,
Pid
,
#state
{
downstreams
=
Ds
,
upstreams
=
Us
}
=
St
)
->
downstream_monitors
=
DsM
,
case
maps
:
take
(
MaybeUpstream
,
Us
)
of
upstreams
=
Us
,
pending_downstreams
=
Pending
}
=
St
)
->
case
maps
:
take
(
Pid
,
Us
)
of
{{
Downstream
,
MonRef
},
Us1
}
->
{{
Downstream
,
MonRef
},
Us1
}
->
ok
=
mtp_down_conn
:
upstream_closed
(
Downstream
,
MaybeUpstream
),
ok
=
mtp_down_conn
:
upstream_closed
(
Downstream
,
Pid
),
Ds1
=
ds_return
(
Downstream
,
Ds
),
Ds1
=
ds_return
(
Downstream
,
Ds
),
St
#state
{
downstreams
=
Ds1
,
St
#state
{
downstreams
=
Ds1
,
upstreams
=
Us1
};
upstreams
=
Us1
};
error
->
error
->
lager
:
warning
(
"Unexpected DOWN. ref=
~p
, pid=
~p
"
,
[
MonRef
,
MaybeUpstream
]),
case
maps
:
take
(
MonRef
,
DsM
)
of
{
Pid
,
DsM1
}
->
Pending1
=
lists
:
delete
(
Pid
,
Pending
),
Ds1
=
ds_remove
(
Pid
,
Ds
),
lager
:
warning
(
"Downstream=
~p
is down"
,
[
Pid
]),
St
#state
{
pending_downstreams
=
Pending1
,
downstreams
=
Ds1
,
downstream_monitors
=
DsM1
};
_
->
lager
:
warning
(
"Unexpected DOWN. ref=
~p
, pid=
~p
"
,
[
MonRef
,
Pid
]),
St
St
end
end
.
end
.
maybe_spawn_connection
(
CurrentMin
,
#state
{
pending_downstreams
=
Pending
}
=
St
)
->
maybe_spawn_connection
(
CurrentMin
,
#state
{
pending_downstreams
=
Pending
}
=
St
)
->
...
@@ -167,18 +187,23 @@ maybe_spawn_connection(CurrentMin, #state{pending_downstreams = Pending} = St) -
...
@@ -167,18 +187,23 @@ maybe_spawn_connection(CurrentMin, #state{pending_downstreams = Pending} = St) -
_
->
_
->
0
0
end
,
end
,
connect_many
(
ToSpawn
,
St
).
connect_many
(
ToSpawn
,
St
)
->
lists
:
foldl
(
lists
:
foldl
(
fun
(_,
S
)
->
fun
(_,
S
)
->
connect
(
S
)
connect
(
S
)
end
,
St
,
lists
:
seq
(
1
,
ToSpawn
)).
end
,
St
,
lists
:
seq
(
1
,
ToSpawn
)).
%% Initiate new async connection
%% Initiate new async connection
connect
(
#state
{
pending_downstreams
=
Pending
,
connect
(
#state
{
pending_downstreams
=
Pending
,
downstream_monitors
=
DsM
,
dc_id
=
DcId
}
=
St
)
->
dc_id
=
DcId
}
=
St
)
->
%% Should monitor connection PIDs as well!
%% Should monitor connection PIDs as well!
Pid
=
do_connect
(
DcId
),
Pid
=
do_connect
(
DcId
),
St
#state
{
pending_downstreams
=
[
Pid
|
Pending
]}.
MonRef
=
erlang
:
monitor
(
process
,
Pid
),
St
#state
{
pending_downstreams
=
[
Pid
|
Pending
],
downstream_monitors
=
DsM
#
{
MonRef
=>
Pid
}}.
%% Asynchronous connect
%% Asynchronous connect
do_connect
(
DcId
)
->
do_connect
(
DcId
)
->
...
@@ -186,12 +211,18 @@ do_connect(DcId) ->
...
@@ -186,12 +211,18 @@ do_connect(DcId) ->
Pid
.
Pid
.
%% Block until all async connections are acked
%% Block until all async connections are acked
recv_pending
(
Pids
)
->
wait_pending
(
#state
{
pending_downstreams
=
Pending
}
=
St
)
->
[
receive
lists
:
foldl
(
fun
(
Pid
,
#state
{
pending_downstreams
=
[
Pid
|
Remaining
],
downstreams
=
Ds
}
=
St1
)
->
receive
{
'$gen_cast'
,
{
connected
,
Pid
}}
->
Pid
{
'$gen_cast'
,
{
connected
,
Pid
}}
->
Pid
after
10000
->
after
10000
->
exit
({
timeout
,
receive
Smth
->
Smth
after
0
->
none
end
})
exit
({
timeout
,
receive
Smth
->
Smth
after
0
->
none
end
})
end
||
Pid
<-
Pids
].
end
,
St1
#state
{
pending_downstreams
=
Remaining
,
downstreams
=
ds_add_downstream
(
Pid
,
Ds
)}
end
,
St
,
Pending
).
%% New downstream connection storage
%% New downstream connection storage
-
spec
ds_new
([
downstream
()])
->
ds_store
().
-
spec
ds_new
([
downstream
()])
->
ds_store
().
...
@@ -228,3 +259,7 @@ ds_get(St) ->
...
@@ -228,3 +259,7 @@ ds_get(St) ->
ds_return
(
Pid
,
St
)
->
ds_return
(
Pid
,
St
)
->
{
ok
,
St1
}
=
pid_psq
:
dec_priority
(
Pid
,
St
),
{
ok
,
St1
}
=
pid_psq
:
dec_priority
(
Pid
,
St
),
St1
.
St1
.
-
spec
ds_remove
(
downstream
(),
ds_store
())
->
ds_store
().
ds_remove
(
Downstream
,
St
)
->
pid_psq
:
delete
(
Downstream
,
St
).
src/mtp_down_conn.erl
View file @
91b89061
...
@@ -129,9 +129,14 @@ code_change(_OldVsn, State, _Extra) ->
...
@@ -129,9 +129,14 @@ code_change(_OldVsn, State, _Extra) ->
%% Send packet from upstream to downstream
%% Send packet from upstream to downstream
handle_send
(
Data
,
Upstream
,
#state
{
upstreams
=
Ups
,
handle_send
(
Data
,
Upstream
,
#state
{
upstreams
=
Ups
,
addr_bin
=
ProxyAddr
}
=
St
)
->
addr_bin
=
ProxyAddr
}
=
St
)
->
UpstreamData
=
maps
:
get
(
Upstream
,
Ups
),
case
Ups
of
#
{
Upstream
:
=
UpstreamData
}
->
Packet
=
mtp_rpc
:
encode_packet
({
data
,
Data
},
{
UpstreamData
,
ProxyAddr
}),
Packet
=
mtp_rpc
:
encode_packet
({
data
,
Data
},
{
UpstreamData
,
ProxyAddr
}),
down_send
(
Packet
,
St
).
down_send
(
Packet
,
St
);
_
->
lager
:
warning
(
"Upstream=
~p
not found"
,
[
Upstream
]),
{{
error
,
unknown_upstream
},
St
}
end
.
%% New upstream connected
%% New upstream connected
handle_upstream_new
(
Upstream
,
Opts
,
#state
{
upstreams
=
Ups
,
handle_upstream_new
(
Upstream
,
Opts
,
#state
{
upstreams
=
Ups
,
...
@@ -141,6 +146,7 @@ handle_upstream_new(Upstream, Opts, #state{upstreams = Ups,
...
@@ -141,6 +146,7 @@ handle_upstream_new(Upstream, Opts, #state{upstreams = Ups,
AdTag
=
maps
:
get
(
ad_tag
,
Opts
,
undefined
),
AdTag
=
maps
:
get
(
ad_tag
,
Opts
,
undefined
),
Ups1
=
Ups
#
{
Upstream
=>
{
ConnId
,
iolist_to_binary
(
mtp_rpc
:
encode_ip_port
(
Ip
,
Port
)),
AdTag
}},
Ups1
=
Ups
#
{
Upstream
=>
{
ConnId
,
iolist_to_binary
(
mtp_rpc
:
encode_ip_port
(
Ip
,
Port
)),
AdTag
}},
UpsRev1
=
UpsRev
#
{
ConnId
=>
Upstream
},
UpsRev1
=
UpsRev
#
{
ConnId
=>
Upstream
},
lager
:
debug
(
"New upstream=
~p
conn_id=
~p
"
,
[
Upstream
,
ConnId
]),
St
#state
{
upstreams
=
Ups1
,
St
#state
{
upstreams
=
Ups1
,
upstreams_rev
=
UpsRev1
}.
upstreams_rev
=
UpsRev1
}.
...
@@ -231,9 +237,10 @@ up_send(Packet, ConnId, #state{upstreams_rev = UpsRev} = St) ->
...
@@ -231,9 +237,10 @@ up_send(Packet, ConnId, #state{upstreams_rev = UpsRev} = St) ->
St
;
St
;
error
->
error
->
lager
:
warning
(
"Unknown connection_id=
~w
"
,
[
ConnId
]),
lager
:
warning
(
"Unknown connection_id=
~w
"
,
[
ConnId
]),
ClosedPacket
=
mtp_rpc
:
encode_packet
(
remote_closed
,
ConnId
),
%% WHY!!!?
{
ok
,
St1
}
=
down_send
(
ClosedPacket
,
St
),
%% ClosedPacket = mtp_rpc:encode_packet(remote_closed, ConnId),
St1
%% {ok, St1} = down_send(ClosedPacket, St),
St
end
.
end
.
connect
(
DcId
,
S
)
->
connect
(
DcId
,
S
)
->
...
...
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