mirror of
https://github.com/processone/ejabberd.git
synced 2024-12-02 16:37:52 +01:00
Merge from trunk r1600:
* src/ejabberd_rdbms.erl: fix SQL database reconnection issues (EJAB-764) and add odbc_start_interval configuration directive (default to 30 seconds). * src/odbc/ejabberd_odbc.erl: likewise. * src/odbc/ejabberd_odbc_sup.erl: likewise. * doc/guide.tex: likewise. SVN Revision: 1601
This commit is contained in:
parent
7224ec8cb4
commit
a4ee23edfe
@ -1,3 +1,12 @@
|
|||||||
|
2008-10-06 Jerome Sautret <jerome.sautret@process-one.net>
|
||||||
|
|
||||||
|
* src/ejabberd_rdbms.erl: fix SQL database reconnection
|
||||||
|
issues (EJAB-764) and add odbc_start_interval configuration
|
||||||
|
directive (default to 30 seconds).
|
||||||
|
* src/odbc/ejabberd_odbc.erl: likewise.
|
||||||
|
* src/odbc/ejabberd_odbc_sup.erl: likewise.
|
||||||
|
* doc/guide.tex: likewise.
|
||||||
|
|
||||||
2008-10-03 Jerome Sautret <jerome.sautret@process-one.net>
|
2008-10-03 Jerome Sautret <jerome.sautret@process-one.net>
|
||||||
|
|
||||||
* src/odbc/odbc_queries.erl: Fix syntax error on update_roster_sql query.
|
* src/odbc/odbc_queries.erl: Fix syntax error on update_roster_sql query.
|
||||||
|
190
doc/guide.tex
190
doc/guide.tex
@ -1388,6 +1388,152 @@ Examples:
|
|||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
|
||||||
|
<<<<<<< .courant
|
||||||
|
=======
|
||||||
|
Appendix \ref{i18ni10n} provides more details about internationalization and localization.
|
||||||
|
|
||||||
|
|
||||||
|
\makesubsection{includeconfigfile}{Include Additional Configuration Files}
|
||||||
|
\ind{options!includeconfigfile}\ind{includeconfigfile}
|
||||||
|
|
||||||
|
The option \option{include\_config\_file} in a configuration file instructs \ejabberd{} to include other configuration files immediately.
|
||||||
|
|
||||||
|
The basic usage is:
|
||||||
|
\begin{verbatim}
|
||||||
|
{include_config_file, <filename>}.
|
||||||
|
\end{verbatim}
|
||||||
|
It is also possible to specify suboptions:
|
||||||
|
\begin{verbatim}
|
||||||
|
{include_config_file, <filename>, [<suboption>, <suboption>, ...]}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
The filename can be indicated either as an absolute path,
|
||||||
|
or relative to the main \ejabberd{} configuration file.
|
||||||
|
It isn't possible to use wildcards.
|
||||||
|
The file must exist and be readable.
|
||||||
|
|
||||||
|
The allowed suboptions are:
|
||||||
|
\begin{description}
|
||||||
|
\titem{\{disallow, [<option>, <option>, ...]\}} Disallows the usage of those options in the included configuration file.
|
||||||
|
The options that match this criteria are not accepted.
|
||||||
|
The default value is an empty list: \term{[]}
|
||||||
|
\titem{\{allow\_only, [<option>, <option>, ...]\}} Allows only the usage of those options in the included configuration file.
|
||||||
|
The options that do not match this criteria are not accepted.
|
||||||
|
The default value is: \term{all}
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
This is a basic example:
|
||||||
|
\begin{verbatim}
|
||||||
|
{include_config_file, "/etc/ejabberd/additional.cfg"}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
In this example, the included file is not allowed to contain a \term{listen} option.
|
||||||
|
If such an option is present, the option will not be accepted.
|
||||||
|
The file is in a subdirectory from where the main configuration file is.
|
||||||
|
\begin{verbatim}
|
||||||
|
{include_config_file, "./example.org/additional_not_listen.cfg", [{disallow, [listen]}]}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
In this example, \term{ejabberd.cfg} defines some ACL and Access rules,
|
||||||
|
and later includes another file with additional rules:
|
||||||
|
\begin{verbatim}
|
||||||
|
{acl, admin, {user, "admin", "localhost"}}.
|
||||||
|
{access, announce, [{allow, admin}]}.
|
||||||
|
{include_config_file, "/etc/ejabberd/acl_and_access.cfg", [{allow_only, [acl, access]}]}.
|
||||||
|
\end{verbatim}
|
||||||
|
and content of the file \term{acl\_and\_access.cfg} can be, for example:
|
||||||
|
\begin{verbatim}
|
||||||
|
{acl, admin, {user, "bob", "localhost"}}.
|
||||||
|
{acl, admin, {user, "jan", "localhost"}}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
|
\makesubsection{optionmacros}{Option Macros in Configuration File}
|
||||||
|
\ind{options!optionmacros}\ind{optionmacros}
|
||||||
|
|
||||||
|
In the \ejabberd{} configuration file,
|
||||||
|
it is possible to define a macro for a value
|
||||||
|
and later use this macro when defining an option.
|
||||||
|
|
||||||
|
A macro is defined with this syntax:
|
||||||
|
\begin{verbatim}
|
||||||
|
{define_macro, '<MACRO>', <value>}.
|
||||||
|
\end{verbatim}
|
||||||
|
The \term{MACRO} must be surrounded by single quotation marks,
|
||||||
|
and all letters in uppercase; check the examples bellow.
|
||||||
|
The \term{value} can be any valid arbitrary Erlang term.
|
||||||
|
|
||||||
|
The first definition of a macro is preserved,
|
||||||
|
and additional definitions of the same macro are forgotten.
|
||||||
|
|
||||||
|
Macros are processed after
|
||||||
|
additional configuration files have been included,
|
||||||
|
so it is possible to use macros that
|
||||||
|
are defined in configuration files included before the usage.
|
||||||
|
|
||||||
|
It isn't possible to use a macro in the definition
|
||||||
|
of another macro.
|
||||||
|
|
||||||
|
There are two ways to use a macro:
|
||||||
|
\begin{description}
|
||||||
|
|
||||||
|
\titem{'<MACRO>'}
|
||||||
|
You can put this instead of a value in an \ejabberd{} option,
|
||||||
|
and will be replaced with the \term{value} previously defined.
|
||||||
|
If the macro is not defined previously,
|
||||||
|
the program will crash and report an error.
|
||||||
|
|
||||||
|
\titem{\{use\_macro, '<MACRO>', <defaultvalue>\}}
|
||||||
|
Use a macro even if it may not be defined.
|
||||||
|
If the macro is not defined previously,
|
||||||
|
the provided \term{defaultvalue} is used.
|
||||||
|
This usage behaves as if it were defined and used this way:
|
||||||
|
\begin{verbatim}
|
||||||
|
{define_macro, '<MACRO>', <defaultvalue>}.
|
||||||
|
'<MACRO>'
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
This example shows the basic usage of a macro:
|
||||||
|
\begin{verbatim}
|
||||||
|
{define_macro, 'LOG_LEVEL_NUMBER', 5}.
|
||||||
|
{loglevel, 'LOG_LEVEL_NUMBER'}.
|
||||||
|
\end{verbatim}
|
||||||
|
The resulting option interpreted by \ejabberd{} is: \term{\{loglevel, 5\}}.
|
||||||
|
|
||||||
|
This example shows that values can be any arbitrary Erlang term:
|
||||||
|
\begin{verbatim}
|
||||||
|
{define_macro, 'USERBOB', {user, "bob", "localhost"}}.
|
||||||
|
{acl, admin, 'USERBOB'}.
|
||||||
|
\end{verbatim}
|
||||||
|
The resulting option interpreted by \ejabberd{} is: \term{\{acl, admin, \{user, "bob", "localhost"\}\}}.
|
||||||
|
|
||||||
|
This complex example:
|
||||||
|
\begin{verbatim}
|
||||||
|
{define_macro, 'NUMBER_PORT_C2S', 5222}.
|
||||||
|
{define_macro, 'PORT_S2S_IN', {5269, ejabberd_s2s_in, []}}.
|
||||||
|
{listen,
|
||||||
|
[
|
||||||
|
{'NUMBER_PORT_C2S', ejabberd_c2s, []},
|
||||||
|
'PORT_S2S_IN',
|
||||||
|
{{use_macro, 'NUMBER_PORT_HTTP', 5280}, ejabberd_http, []}
|
||||||
|
]
|
||||||
|
}.
|
||||||
|
\end{verbatim}
|
||||||
|
produces this result after being interpreted:
|
||||||
|
\begin{verbatim}
|
||||||
|
{listen,
|
||||||
|
[
|
||||||
|
{5222, ejabberd_c2s, []},
|
||||||
|
{5269, ejabberd_s2s_in, []},
|
||||||
|
{5280, ejabberd_http, []}
|
||||||
|
]
|
||||||
|
}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
|
>>>>>>> .fusion-droit.r1600
|
||||||
\makesection{database}{Database and LDAP Configuration}
|
\makesection{database}{Database and LDAP Configuration}
|
||||||
\ind{database}
|
\ind{database}
|
||||||
%TODO: this whole section is not yet 100% optimized
|
%TODO: this whole section is not yet 100% optimized
|
||||||
@ -1444,6 +1590,13 @@ Specify in seconds: for example 28800 means 8 hours.
|
|||||||
{odbc_keepalive_interval, undefined}.
|
{odbc_keepalive_interval, undefined}.
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
|
|
||||||
|
If the connection to the database fails, \ejabberd{} waits 30 seconds before retrying.
|
||||||
|
You can modify this interval with this option:
|
||||||
|
\begin{verbatim}
|
||||||
|
{odbc_start_interval, 30}.
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
|
|
||||||
\makesubsubsection{compilemysql}{Driver Compilation}
|
\makesubsubsection{compilemysql}{Driver Compilation}
|
||||||
\ind{MySQL!Driver Compilation}
|
\ind{MySQL!Driver Compilation}
|
||||||
|
|
||||||
@ -2672,6 +2825,14 @@ Options:
|
|||||||
This option sets the full path to the directory in which the HTML files should
|
This option sets the full path to the directory in which the HTML files should
|
||||||
be stored. Make sure the \ejabberd{} daemon user has write access on that
|
be stored. Make sure the \ejabberd{} daemon user has write access on that
|
||||||
directory. The default value is \term{"www/muc"}.
|
directory. The default value is \term{"www/muc"}.
|
||||||
|
<<<<<<< .courant
|
||||||
|
=======
|
||||||
|
\titem{spam\_prevention}\ind{options!spam\_prevention}
|
||||||
|
To prevent spam, the \term{spam\_prevention} option adds a special attribute
|
||||||
|
to links that prevent their indexation by search engines. The default value
|
||||||
|
is \term{true}, which mean that nofollow attributes will be added to user
|
||||||
|
submitted links.
|
||||||
|
>>>>>>> .fusion-droit.r1600
|
||||||
\titem{timezone}\ind{options!timezone}
|
\titem{timezone}\ind{options!timezone}
|
||||||
The time zone for the logs is configurable with this option. Allowed values
|
The time zone for the logs is configurable with this option. Allowed values
|
||||||
are \term{local} and \term{universal}. With the first value, the local time,
|
are \term{local} and \term{universal}. With the first value, the local time,
|
||||||
@ -3592,8 +3753,16 @@ The command line parameters:
|
|||||||
\titem{-name ejabberd}
|
\titem{-name ejabberd}
|
||||||
The Erlang node will be fully identified.
|
The Erlang node will be fully identified.
|
||||||
This is only useful if you plan to setup an \ejabberd{} cluster with nodes in different networks.
|
This is only useful if you plan to setup an \ejabberd{} cluster with nodes in different networks.
|
||||||
|
<<<<<<< .courant
|
||||||
\titem{-kernel inetrc "/etc/ejabberd/inetrc"}
|
\titem{-kernel inetrc "/etc/ejabberd/inetrc"}
|
||||||
Indicates which IP name resolution to use. It is required if using \term{-sname}.
|
Indicates which IP name resolution to use. It is required if using \term{-sname}.
|
||||||
|
=======
|
||||||
|
\titem{-kernel inetrc "/etc/ejabberd/inetrc"}
|
||||||
|
Indicates which IP name resolution to use.
|
||||||
|
If using \term{-sname}, specify either this option or \term{ERL\_INETRC}.
|
||||||
|
\titem{-kernel inet\_dist\_listen\_min 4200 inet\_dist\_listen\_min 4210}
|
||||||
|
Define the first and last ports that \term{epmd} (section \ref{epmd}) can listen to.
|
||||||
|
>>>>>>> .fusion-droit.r1600
|
||||||
\titem{-detached}
|
\titem{-detached}
|
||||||
Starts the Erlang system detached from the system console.
|
Starts the Erlang system detached from the system console.
|
||||||
Useful for running daemons and backgrounds processes.
|
Useful for running daemons and backgrounds processes.
|
||||||
@ -3775,8 +3944,14 @@ Remember to block the port so Internet doesn't have access to it.
|
|||||||
|
|
||||||
Once an Erlang node solved the node name of another Erlang node using EPMD and port 4369,
|
Once an Erlang node solved the node name of another Erlang node using EPMD and port 4369,
|
||||||
the nodes communicate directly.
|
the nodes communicate directly.
|
||||||
|
<<<<<<< .courant
|
||||||
The ports used in this case are random.
|
The ports used in this case are random.
|
||||||
You can limit the range of ports when starting Erlang with a command-line parameter, for example:
|
You can limit the range of ports when starting Erlang with a command-line parameter, for example:
|
||||||
|
=======
|
||||||
|
The ports used in this case by default are random,
|
||||||
|
but can be configured in the file \term{ejabberdctl.cfg}.
|
||||||
|
The Erlang command-line parameter used internally is, for example:
|
||||||
|
>>>>>>> .fusion-droit.r1600
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
|
erl ... -kernel inet_dist_listen_min 4370 inet_dist_listen_max 4375
|
||||||
\end{verbatim}
|
\end{verbatim}
|
||||||
@ -4101,6 +4276,21 @@ To exit the shell, close the window or press the keys: control+c control+c.
|
|||||||
\makechapter{i18ni10n}{Internationalization and Localization}
|
\makechapter{i18ni10n}{Internationalization and Localization}
|
||||||
\ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n}
|
\ind{xml:lang}\ind{internationalization}\ind{localization}\ind{i18n}\ind{l10n}
|
||||||
|
|
||||||
|
<<<<<<< .courant
|
||||||
|
=======
|
||||||
|
The source code of \ejabberd{} supports localization.
|
||||||
|
The translators can edit the
|
||||||
|
\footahref{http://www.gnu.org/software/gettext/}{gettext} .po files
|
||||||
|
using any capable program (KBabel, Lokalize, Poedit...) or a simple text editor.
|
||||||
|
|
||||||
|
Then gettext
|
||||||
|
is used to extract, update and export those .po files to the .msg format read by \ejabberd{}.
|
||||||
|
To perform those management tasks, in the \term{src/} directory execute \term{make translations}.
|
||||||
|
The translatable strings are extracted from source code to generate the file \term{ejabberd.pot}.
|
||||||
|
This file is merged with each .po file to produce updated .po files.
|
||||||
|
Finally those .po files are exported to .msg files, that have a format easily readable by \ejabberd{}.
|
||||||
|
|
||||||
|
>>>>>>> .fusion-droit.r1600
|
||||||
All built-in modules support the \texttt{xml:lang} attribute inside IQ queries.
|
All built-in modules support the \texttt{xml:lang} attribute inside IQ queries.
|
||||||
Figure~\ref{fig:discorus}, for example, shows the reply to the following query:
|
Figure~\ref{fig:discorus}, for example, shows the reply to the following query:
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
|
@ -52,14 +52,21 @@ start_hosts() ->
|
|||||||
|
|
||||||
%% Start the ODBC module on the given host
|
%% Start the ODBC module on the given host
|
||||||
start_odbc(Host) ->
|
start_odbc(Host) ->
|
||||||
|
Supervisor_name = gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
|
||||||
ChildSpec =
|
ChildSpec =
|
||||||
{gen_mod:get_module_proc(Host, ejabberd_odbc_sup),
|
{Supervisor_name,
|
||||||
{ejabberd_odbc_sup, start_link, [Host]},
|
{ejabberd_odbc_sup, start_link, [Host]},
|
||||||
temporary,
|
transient,
|
||||||
infinity,
|
infinity,
|
||||||
supervisor,
|
supervisor,
|
||||||
[ejabberd_odbc_sup]},
|
[ejabberd_odbc_sup]},
|
||||||
supervisor:start_child(ejabberd_sup, ChildSpec).
|
case supervisor:start_child(ejabberd_sup, ChildSpec) of
|
||||||
|
{ok, _PID} ->
|
||||||
|
ok;
|
||||||
|
_Error ->
|
||||||
|
?ERROR_MSG("Start of supervisor ~p failed:~n~p~nRetrying...~n", [Supervisor_name, _Error]),
|
||||||
|
start_odbc(Host)
|
||||||
|
end.
|
||||||
|
|
||||||
%% Returns true if we have configured odbc_server for the given host
|
%% Returns true if we have configured odbc_server for the given host
|
||||||
needs_odbc(Host) ->
|
needs_odbc(Host) ->
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
-behaviour(gen_server).
|
-behaviour(gen_server).
|
||||||
|
|
||||||
%% External exports
|
%% External exports
|
||||||
-export([start/1, start_link/1,
|
-export([start/1, start_link/2,
|
||||||
sql_query/2,
|
sql_query/2,
|
||||||
sql_query_t/1,
|
sql_query_t/1,
|
||||||
sql_transaction/2,
|
sql_transaction/2,
|
||||||
@ -63,8 +63,8 @@
|
|||||||
start(Host) ->
|
start(Host) ->
|
||||||
gen_server:start(ejabberd_odbc, [Host], []).
|
gen_server:start(ejabberd_odbc, [Host], []).
|
||||||
|
|
||||||
start_link(Host) ->
|
start_link(Host, StartInterval) ->
|
||||||
gen_server:start_link(ejabberd_odbc, [Host], []).
|
gen_server:start_link(ejabberd_odbc, [Host, StartInterval], []).
|
||||||
|
|
||||||
sql_query(Host, Query) ->
|
sql_query(Host, Query) ->
|
||||||
gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
|
gen_server:call(ejabberd_odbc_sup:get_random_pid(Host),
|
||||||
@ -131,10 +131,10 @@ escape_like(C) -> odbc_queries:escape(C).
|
|||||||
%% ignore |
|
%% ignore |
|
||||||
%% {stop, Reason}
|
%% {stop, Reason}
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
init([Host]) ->
|
init([Host, StartInterval]) ->
|
||||||
case ejabberd_config:get_local_option({odbc_keepalive_interval, Host}) of
|
case ejabberd_config:get_local_option({odbc_keepalive_interval, Host}) of
|
||||||
Interval when is_integer(Interval) ->
|
KeepaliveInterval when is_integer(KeepaliveInterval) ->
|
||||||
timer:apply_interval(Interval*1000, ?MODULE, keep_alive, [self()]);
|
timer:apply_interval(KeepaliveInterval*1000, ?MODULE, keep_alive, [self()]);
|
||||||
undefined ->
|
undefined ->
|
||||||
ok;
|
ok;
|
||||||
_Other ->
|
_Other ->
|
||||||
@ -144,16 +144,16 @@ init([Host]) ->
|
|||||||
case SQLServer of
|
case SQLServer of
|
||||||
%% Default pgsql port
|
%% Default pgsql port
|
||||||
{pgsql, Server, DB, Username, Password} ->
|
{pgsql, Server, DB, Username, Password} ->
|
||||||
pgsql_connect(Server, ?PGSQL_PORT, DB, Username, Password);
|
pgsql_connect(Server, ?PGSQL_PORT, DB, Username, Password, StartInterval);
|
||||||
{pgsql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
{pgsql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
||||||
pgsql_connect(Server, Port, DB, Username, Password);
|
pgsql_connect(Server, Port, DB, Username, Password, StartInterval);
|
||||||
%% Default mysql port
|
%% Default mysql port
|
||||||
{mysql, Server, DB, Username, Password} ->
|
{mysql, Server, DB, Username, Password} ->
|
||||||
mysql_connect(Server, ?MYSQL_PORT, DB, Username, Password);
|
mysql_connect(Server, ?MYSQL_PORT, DB, Username, Password, StartInterval);
|
||||||
{mysql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
{mysql, Server, Port, DB, Username, Password} when is_integer(Port) ->
|
||||||
mysql_connect(Server, Port, DB, Username, Password);
|
mysql_connect(Server, Port, DB, Username, Password, StartInterval);
|
||||||
_ when is_list(SQLServer) ->
|
_ when is_list(SQLServer) ->
|
||||||
odbc_connect(SQLServer)
|
odbc_connect(SQLServer, StartInterval)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
%%----------------------------------------------------------------------
|
%%----------------------------------------------------------------------
|
||||||
@ -245,7 +245,7 @@ execute_transaction(State, F, NRestarts) ->
|
|||||||
|
|
||||||
%% part of init/1
|
%% part of init/1
|
||||||
%% Open an ODBC database connection
|
%% Open an ODBC database connection
|
||||||
odbc_connect(SQLServer) ->
|
odbc_connect(SQLServer, StartInterval) ->
|
||||||
application:start(odbc),
|
application:start(odbc),
|
||||||
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
|
case odbc:connect(SQLServer,[{scrollable_cursors, off}]) of
|
||||||
{ok, Ref} ->
|
{ok, Ref} ->
|
||||||
@ -254,8 +254,8 @@ odbc_connect(SQLServer) ->
|
|||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
|
?ERROR_MSG("ODBC connection (~s) failed: ~p~n",
|
||||||
[SQLServer, Reason]),
|
[SQLServer, Reason]),
|
||||||
%% If we can't connect we wait for 30 seconds before retrying
|
%% If we can't connect we wait before retrying
|
||||||
timer:sleep(30000),
|
timer:sleep(StartInterval),
|
||||||
{stop, odbc_connection_failed}
|
{stop, odbc_connection_failed}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -264,15 +264,15 @@ odbc_connect(SQLServer) ->
|
|||||||
|
|
||||||
%% part of init/1
|
%% part of init/1
|
||||||
%% Open a database connection to PostgreSQL
|
%% Open a database connection to PostgreSQL
|
||||||
pgsql_connect(Server, Port, DB, Username, Password) ->
|
pgsql_connect(Server, Port, DB, Username, Password, StartInterval) ->
|
||||||
case pgsql:connect(Server, DB, Username, Password, Port) of
|
case pgsql:connect(Server, DB, Username, Password, Port) of
|
||||||
{ok, Ref} ->
|
{ok, Ref} ->
|
||||||
erlang:monitor(process, Ref),
|
erlang:monitor(process, Ref),
|
||||||
{ok, #state{db_ref = Ref, db_type = pgsql}};
|
{ok, #state{db_ref = Ref, db_type = pgsql}};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
|
?ERROR_MSG("PostgreSQL connection failed: ~p~n", [Reason]),
|
||||||
%% If we can't connect we wait for 30 seconds before retrying
|
%% If we can't connect we wait before retrying
|
||||||
timer:sleep(30000),
|
timer:sleep(StartInterval),
|
||||||
{stop, pgsql_connection_failed}
|
{stop, pgsql_connection_failed}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -303,7 +303,7 @@ pgsql_item_to_odbc(_) ->
|
|||||||
|
|
||||||
%% part of init/1
|
%% part of init/1
|
||||||
%% Open a database connection to MySQL
|
%% Open a database connection to MySQL
|
||||||
mysql_connect(Server, Port, DB, Username, Password) ->
|
mysql_connect(Server, Port, DB, Username, Password, StartInterval) ->
|
||||||
NoLogFun = fun(_Level,_Format,_Argument) -> ok end,
|
NoLogFun = fun(_Level,_Format,_Argument) -> ok end,
|
||||||
case mysql_conn:start(Server, Port, Username, Password, DB, NoLogFun) of
|
case mysql_conn:start(Server, Port, Username, Password, DB, NoLogFun) of
|
||||||
{ok, Ref} ->
|
{ok, Ref} ->
|
||||||
@ -311,9 +311,10 @@ mysql_connect(Server, Port, DB, Username, Password) ->
|
|||||||
mysql_conn:fetch(Ref, ["set names 'utf8';"], self()),
|
mysql_conn:fetch(Ref, ["set names 'utf8';"], self()),
|
||||||
{ok, #state{db_ref = Ref, db_type = mysql}};
|
{ok, #state{db_ref = Ref, db_type = mysql}};
|
||||||
{error, Reason} ->
|
{error, Reason} ->
|
||||||
?ERROR_MSG("MySQL connection failed: ~p~n", [Reason]),
|
?ERROR_MSG("MySQL connection failed: ~p~nWaiting ~p seconds before retrying...~n",
|
||||||
%% If we can't connect we wait for 30 seconds before retrying
|
[Reason, StartInterval div 1000]),
|
||||||
timer:sleep(30000),
|
%% If we can't connect we wait before retrying
|
||||||
|
timer:sleep(StartInterval),
|
||||||
{stop, mysql_connection_failed}
|
{stop, mysql_connection_failed}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
@ -37,32 +37,44 @@
|
|||||||
-include("ejabberd.hrl").
|
-include("ejabberd.hrl").
|
||||||
|
|
||||||
-define(DEFAULT_POOL_SIZE, 10).
|
-define(DEFAULT_POOL_SIZE, 10).
|
||||||
|
-define(DEFAULT_ODBC_START_INTERVAL, 30). % 30 seconds
|
||||||
|
|
||||||
start_link(Host) ->
|
start_link(Host) ->
|
||||||
supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
|
supervisor:start_link({local, gen_mod:get_module_proc(Host, ?MODULE)},
|
||||||
?MODULE, [Host]).
|
?MODULE, [Host]).
|
||||||
|
|
||||||
init([Host]) ->
|
init([Host]) ->
|
||||||
N = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of
|
PoolSize = case ejabberd_config:get_local_option({odbc_pool_size, Host}) of
|
||||||
I when is_integer(I) ->
|
I when is_integer(I) ->
|
||||||
I;
|
I;
|
||||||
undefined ->
|
undefined ->
|
||||||
?DEFAULT_POOL_SIZE;
|
?DEFAULT_POOL_SIZE;
|
||||||
Other ->
|
Other ->
|
||||||
?ERROR_MSG("Wrong odbc_pool_size definition '~p' for host ~p, default to ~p~n",
|
?ERROR_MSG("Wrong odbc_pool_size definition '~p' for host ~p, default to ~p~n",
|
||||||
[Other, Host, ?DEFAULT_POOL_SIZE]),
|
[Other, Host, ?DEFAULT_POOL_SIZE]),
|
||||||
?DEFAULT_POOL_SIZE
|
?DEFAULT_POOL_SIZE
|
||||||
end,
|
end,
|
||||||
{ok, {{one_for_one, 10, 6},
|
StartInterval = case ejabberd_config:get_local_option({odbc_start_interval, Host}) of
|
||||||
|
Interval when is_integer(Interval) ->
|
||||||
|
Interval;
|
||||||
|
undefined ->
|
||||||
|
?DEFAULT_ODBC_START_INTERVAL;
|
||||||
|
_Other2 ->
|
||||||
|
?ERROR_MSG("Wrong odbc_start_interval definition '~p' for host ~p"
|
||||||
|
", defaulting to ~p~n",
|
||||||
|
[_Other2, Host, ?DEFAULT_ODBC_START_INTERVAL]),
|
||||||
|
?DEFAULT_ODBC_START_INTERVAL
|
||||||
|
end,
|
||||||
|
{ok, {{one_for_one, PoolSize+1, StartInterval},
|
||||||
lists:map(
|
lists:map(
|
||||||
fun(I) ->
|
fun(I) ->
|
||||||
{I,
|
{I,
|
||||||
{ejabberd_odbc, start_link, [Host]},
|
{ejabberd_odbc, start_link, [Host, StartInterval*1000]},
|
||||||
transient,
|
transient,
|
||||||
brutal_kill,
|
brutal_kill,
|
||||||
worker,
|
worker,
|
||||||
[?MODULE]}
|
[?MODULE]}
|
||||||
end, lists:seq(1, N))}}.
|
end, lists:seq(1, PoolSize))}}.
|
||||||
|
|
||||||
get_pids(Host) ->
|
get_pids(Host) ->
|
||||||
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
Proc = gen_mod:get_module_proc(Host, ?MODULE),
|
||||||
|
Loading…
Reference in New Issue
Block a user