This repository has been archived by the owner on Sep 27, 2023. It is now read-only.
/
logplex_drain.erl
125 lines (112 loc) · 5.25 KB
/
logplex_drain.erl
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
%% Copyright (c) 2010 Jacob Vorreuter <jacob.vorreuter@gmail.com>
%%
%% Permission is hereby granted, free of charge, to any person
%% obtaining a copy of this software and associated documentation
%% files (the "Software"), to deal in the Software without
%% restriction, including without limitation the rights to use,
%% copy, modify, merge, publish, distribute, sublicense, and/or sell
%% copies of the Software, and to permit persons to whom the
%% Software is furnished to do so, subject to the following
%% conditions:
%%
%% The above copyright notice and this permission notice shall be
%% included in all copies or substantial portions of the Software.
%%
%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
%% EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
%% OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
%% NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
%% HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
%% WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
%% FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
%% OTHER DEALINGS IN THE SOFTWARE.
-module(logplex_drain).
-export([reserve_token/0, cache/3, create/5, create/4,
delete/1, delete/3, clear_all/1, lookup/1]).
-include_lib("logplex.hrl").
reserve_token() ->
Token = new_token(),
case redis_helper:drain_index() of
DrainId when is_integer(DrainId) ->
{ok, DrainId, Token};
Err ->
Err
end.
cache(DrainId, Token, ChannelId) when is_integer(DrainId),
is_binary(Token),
is_integer(ChannelId) ->
true = ets:insert(drains, #drain{id=DrainId, channel_id=ChannelId, token=Token}).
create(DrainId, Token, ChannelId, Host, Port) when is_integer(DrainId),
is_binary(Token),
is_integer(ChannelId),
is_binary(Host),
(is_integer(Port) orelse Port == undefined) ->
case ets:match_object(drains, #drain{id='_', channel_id=ChannelId, token='_', resolved_host='_', host=Host, port=Port}) of
[_] ->
{error, already_exists};
[] ->
case logplex_utils:resolve_host(Host) of
undefined ->
error_logger:error_msg("invalid drain: ~p:~p~n", [Host, Port]),
{error, invalid_drain};
_Ip ->
case redis_helper:create_drain(DrainId, ChannelId, Token, Host, Port) of
ok ->
#drain{id=DrainId, channel_id=ChannelId, token=Token, host=Host, port=Port};
Err ->
Err
end
end
end.
create(DrainId, ChannelId, Host, Port) when is_integer(DrainId),
is_integer(ChannelId),
is_binary(Host) ->
case ets:lookup(drains, DrainId) of
[#drain{channel_id=ChannelId, token=Token}] ->
case ets:match_object(drains, #drain{id='_', channel_id=ChannelId, token='_', resolved_host='_', host=Host, port=Port}) of
[_] ->
{error, already_exists};
[] ->
case logplex_utils:resolve_host(Host) of
undefined ->
error_logger:error_msg("invalid drain: ~p:~p~n", [Host, Port]),
{error, invalid_drain};
_Ip ->
case redis_helper:create_drain(DrainId, ChannelId, Token, Host, Port) of
ok -> #drain{id=DrainId, channel_id=ChannelId, token=Token, host=Host, port=Port};
Err -> Err
end
end
end;
_ ->
{error, not_found}
end.
delete(ChannelId, Host, Port) when is_integer(ChannelId), is_binary(Host) ->
Port1 = if Port == "" -> undefined; true -> list_to_integer(Port) end,
case ets:match_object(drains, #drain{id='_', channel_id=ChannelId, token='_', resolved_host='_', host=Host, port=Port1}) of
[#drain{id=DrainId}|_] ->
delete(DrainId);
_ ->
{error, not_found}
end.
delete(DrainId) when is_integer(DrainId) ->
redis_helper:delete_drain(DrainId).
clear_all(ChannelId) when is_integer(ChannelId) ->
List = ets:match_object(drains, #drain{id='_', channel_id=ChannelId, token='_', resolved_host='_', host='_', port='_'}),
[delete(DrainId) || #drain{id=DrainId} <- List],
ok.
lookup(DrainId) when is_integer(DrainId) ->
case ets:lookup(drains, DrainId) of
[Drain] -> Drain;
_ -> undefined
end.
new_token() ->
new_token(10).
new_token(0) ->
exit({error, failed_to_reserve_drain_token});
new_token(Retries) ->
Token = list_to_binary("d." ++ string:strip(os:cmd("uuidgen"), right, $\n)),
case ets:match_object(drains, #drain{id='_', channel_id='_', token=Token, resolved_host='_', host='_', port='_'}) of
[#drain{}] -> new_token(Retries-1);
[] -> Token
end.