Archives
Trending
Support
Login
clear text
XML
Django
JavaScript
MATLAB
C
C++
C#
Python
SQL
Shell
Bash
Markdown
YAML
JSON
HTML
CSS
PHP
Java
Ruby
Go
Rust
Swift
Kotlin
Arduino
TypeScript
Perl
Autohotkey
Lua
SQF
R
Scala
Haskell
Groovy
Dart
Clojure
VB.NET
Objective-C
PowerShell
Bash
CoffeeScript
Verilog
-module(ip_fetcher_app). -behaviour(application). -export([start/2, stop/1]). start(_StartType, _StartArgs) -> ip_fetcher_sup:start_link(). stop(_State) -> ok. %% =================================================================== %% Supervisor %% =================================================================== -module(ip_fetcher_sup). -behaviour(supervisor). -export([start_link/0, init/1]). start_link() -> supervisor:start_link({local, ?MODULE}, ?MODULE, []). init([]) -> SupFlags = #{ strategy => one_for_one, intensity => 3, % max restarts period => 5 % seconds }, ChildSpec = #{ id => ip_fetcher, start => {ip_fetcher_worker, start_link, []}, restart => transient, % only restart on abnormal exit shutdown => 5000, % 5 seconds graceful shutdown type => worker, modules => [ip_fetcher_worker] }, {ok, {SupFlags, [ChildSpec]}}. %% =================================================================== %% Worker %% =================================================================== -module(ip_fetcher_worker). -behaviour(gen_server). -export([start_link/0]). -export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). start_link() -> gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). init([]) -> % Start the work immediately self() ! fetch_ip, {ok, #{}}. handle_call(_Request, _From, State) -> {reply, ok, State}. handle_cast(_Msg, State) -> {noreply, State}. handle_info(fetch_ip, State) -> case do_fetch_ip() of {ok, Ip} -> io:format("~s~n", [Ip]), % Normal exit — transient worker will NOT be restarted {stop, normal, State}; {error, Reason} -> io:format("Failed to connect – will be restarted by supervisor: ~p~n", [Reason]), % Abnormal exit — supervisor WILL restart us (up to 3 times in 5s) {stop, {connect_failed, Reason}, State} end; handle_info(_Info, State) -> {noreply, State}. terminate(_Reason, _State) -> ok. code_change(_OldVsn, State, _Extra) -> {ok, State}. %% Internal function to fetch IP do_fetch_ip() -> Host = "icanhazip.com", Port = 80, Timeout = 10000, case gen_tcp:connect(Host, Port, [binary, {active, false}], Timeout) of {ok, Socket} -> Request = "GET / HTTP/1.0\r\nHost: icanhazip.com\r\nConnection: close\r\n\r\n", ok = gen_tcp:send(Socket, Request), case recv_all(Socket, <<>>) of {ok, Data} -> % Extract just the IP (last line) Lines = binary:split(Data, <<"\n">>, [global, trim]), Ip = lists:last(Lines), gen_tcp:close(Socket), {ok, binary_to_list(Ip)}; Error -> gen_tcp:close(Socket), Error end; Error -> Error end. recv_all(Socket, Acc) -> case gen_tcp:recv(Socket, 0, 10000) of {ok, Data} -> recv_all(Socket, <
>); {error, closed} -> {ok, Acc}; {error, _} = Err -> Err end.
Mark as private (unlisted)
for 30 minutes
for 6 hours
for 1 day
for 1 week
for 1 month
for 1 year
everlasting (like CCCP)