Compare commits
No commits in common. "master" and "V1.1.13" have entirely different histories.
|
|
@ -31,4 +31,3 @@ src/Makefile
|
||||||
|
|
||||||
# other
|
# other
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
|
||||||
|
|
|
||||||
|
|
@ -1,185 +1,4 @@
|
||||||
libserverframe (1.2.11-1) unstable; urgency=medium
|
libserverframe (1.1.12-1) UNRELEASED; urgency=medium
|
||||||
|
|
||||||
* upgrade to 1.2.11-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 23 Nov 2025 10:48:22 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.11-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.11-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 23 Nov 2025 10:00:56 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.11-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.11-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 23 Nov 2025 09:06:43 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.8-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.8-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sat, 16 Aug 2025 16:32:03 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.7-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.7-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 06 Apr 2025 16:56:40 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.5-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.5-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 29 Sep 2024 15:24:39 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.4-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.4-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sat, 15 Jun 2024 14:45:44 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.3-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.3-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 17 Mar 2024 15:11:04 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.2-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.2-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Wed, 31 Jan 2024 12:00:10 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.1-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.1-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Mon, 01 Jan 2024 11:24:45 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.0-3) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.0-3
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Tue, 21 Nov 2023 14:36:16 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.0-2) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.0-2
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Mon, 20 Nov 2023 13:24:02 +0000
|
|
||||||
|
|
||||||
libserverframe (1.2.0-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.2.0-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 19 Nov 2023 14:46:16 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.29-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.29-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 06 Aug 2023 07:22:46 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.28-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.28-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 23 Jul 2023 14:28:20 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.27-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.27-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sat, 24 Jun 2023 06:51:30 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.26-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.26-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 04 Jun 2023 10:52:11 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.25-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.25-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sat, 18 Feb 2023 05:44:50 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.24-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.24-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 15 Jan 2023 13:50:15 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.22-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.22-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Mon, 21 Nov 2022 14:55:50 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.21-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.21-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sat, 08 Oct 2022 13:28:40 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.20-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.20-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Thu, 22 Sep 2022 12:22:39 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.18-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.18-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Wed, 07 Sep 2022 13:36:38 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.17-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.17-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Mon, 15 Aug 2022 13:31:54 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.16-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.16-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Mon, 25 Jul 2022 13:52:09 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.15-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.15-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Wed, 15 Jun 2022 14:26:27 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.14-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade to 1.1.14-1
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Thu, 28 Apr 2022 11:54:26 +0000
|
|
||||||
|
|
||||||
libserverframe (1.1.13-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* add files: sf_iov.[hc]
|
|
||||||
* iova_slice error detect
|
|
||||||
* sf_iova_memset impl.
|
|
||||||
* sf_iova_memset_ex for iov and iovcnt
|
|
||||||
* sf_iova_memset_ex: add const modifier
|
|
||||||
* sf_iov.[hc] add function sf_iova_memcpy_ex
|
|
||||||
* simple_hash rename to fc_simple_hash
|
|
||||||
* change log level to debug
|
|
||||||
* add function sf_load_global_base_path
|
|
||||||
* support function sf_sharding_htable_delete
|
|
||||||
* sf_load_global_config_ex: server_name can be NULL
|
|
||||||
* upgrade version to 1.1.13
|
|
||||||
* make.sh: change DEBUG_FLAG to 0
|
|
||||||
* add function sf_binlog_writer_get_index_filename
|
|
||||||
|
|
||||||
-- YuQing <384681@qq.com> Sun, 13 Mar 2022 16:46:17 +0800
|
|
||||||
|
|
||||||
libserverframe (1.1.12-1) unstable; urgency=medium
|
|
||||||
|
|
||||||
* upgrade version to 1.1.12
|
* upgrade version to 1.1.12
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ Section: net
|
||||||
Priority: optional
|
Priority: optional
|
||||||
Maintainer: YuQing <384681@qq.com>
|
Maintainer: YuQing <384681@qq.com>
|
||||||
Build-Depends: debhelper (>=11~)
|
Build-Depends: debhelper (>=11~)
|
||||||
, libfastcommon-dev (>= 1.0.56)
|
, libfastcommon-dev (>= 1.0.55)
|
||||||
Standards-Version: 4.1.4
|
Standards-Version: 4.1.4
|
||||||
Homepage: https://github.com/happyfish100/libserverframe
|
Homepage: https://github.com/happyfish100/libserverframe
|
||||||
|
|
||||||
|
|
@ -12,7 +12,7 @@ Section: net
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Pre-Depends: ${misc:Pre-Depends}
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
Depends: ${misc:Depends}, libserverframe (= ${binary:Version})
|
Depends: ${misc:Depends}, ${shlibs:Depends}, libserverframe (= ${binary:Version})
|
||||||
Description: libserverframe (development files)
|
Description: libserverframe (development files)
|
||||||
This package contains header files.
|
This package contains header files.
|
||||||
|
|
||||||
|
|
@ -21,5 +21,5 @@ Section: net
|
||||||
Architecture: any
|
Architecture: any
|
||||||
Multi-Arch: same
|
Multi-Arch: same
|
||||||
Pre-Depends: ${misc:Pre-Depends}
|
Pre-Depends: ${misc:Pre-Depends}
|
||||||
Depends: ${misc:Depends}, ${shlibs:Depends}, libfastcommon (>= ${libfastcommon:Version})
|
Depends: ${misc:Depends}, ${shlibs:Depends}, libfastcommon (>= 1.0.55)
|
||||||
Description: this network service framework library extract from FastDFS
|
Description: this network service framework library extract from FastDFS
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,45 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||||
Upstream-Name: libserverframe
|
Upstream-Name: libserverframe
|
||||||
Source: https://github.com/happyfish100/libserverframe
|
Source: https://github.com/happyfish100/libserverframe
|
||||||
|
|
||||||
Files: *
|
Files: src/idempotency/client/client_channel.c
|
||||||
|
src/idempotency/client/client_channel.h
|
||||||
|
src/idempotency/client/client_types.h
|
||||||
|
src/idempotency/client/receipt_handler.c
|
||||||
|
src/idempotency/client/receipt_handler.h
|
||||||
|
src/idempotency/client/rpc_wrapper.h
|
||||||
|
src/idempotency/server/channel_htable.c
|
||||||
|
src/idempotency/server/channel_htable.h
|
||||||
|
src/idempotency/server/request_htable.c
|
||||||
|
src/idempotency/server/request_htable.h
|
||||||
|
src/idempotency/server/server_channel.c
|
||||||
|
src/idempotency/server/server_channel.h
|
||||||
|
src/idempotency/server/server_handler.c
|
||||||
|
src/idempotency/server/server_handler.h
|
||||||
|
src/idempotency/server/server_types.h
|
||||||
|
src/sf_binlog_writer.c
|
||||||
|
src/sf_binlog_writer.h
|
||||||
|
src/sf_cluster_cfg.c
|
||||||
|
src/sf_cluster_cfg.h
|
||||||
|
src/sf_configs.c
|
||||||
|
src/sf_configs.h
|
||||||
|
src/sf_connection_manager.c
|
||||||
|
src/sf_connection_manager.h
|
||||||
|
src/sf_define.h
|
||||||
|
src/sf_func.c
|
||||||
|
src/sf_func.h
|
||||||
|
src/sf_global.c
|
||||||
|
src/sf_global.h
|
||||||
|
src/sf_nio.c
|
||||||
|
src/sf_nio.h
|
||||||
|
src/sf_proto.c
|
||||||
|
src/sf_proto.h
|
||||||
|
src/sf_service.c
|
||||||
|
src/sf_service.h
|
||||||
|
src/sf_sharding_htable.c
|
||||||
|
src/sf_sharding_htable.h
|
||||||
|
src/sf_types.h
|
||||||
|
src/sf_util.c
|
||||||
|
src/sf_util.h
|
||||||
Copyright: 2020 YuQing <384681@qq.com>
|
Copyright: 2020 YuQing <384681@qq.com>
|
||||||
License: AGPL-3.0+
|
License: AGPL-3.0+
|
||||||
This program is free software: you can use, redistribute, and/or modify
|
This program is free software: you can use, redistribute, and/or modify
|
||||||
|
|
@ -16,6 +54,39 @@ License: AGPL-3.0+
|
||||||
You should have received a copy of the GNU Affero General Public License
|
You should have received a copy of the GNU Affero General Public License
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Files: .gitignore
|
||||||
|
README.md
|
||||||
|
libserverframe.spec
|
||||||
|
make.sh
|
||||||
|
sample.conf
|
||||||
|
src/Makefile
|
||||||
|
src/Makefile.in
|
||||||
|
src/idempotency/client/client_channel.lo
|
||||||
|
src/idempotency/client/receipt_handler.lo
|
||||||
|
src/idempotency/server/channel_htable.lo
|
||||||
|
src/idempotency/server/request_htable.lo
|
||||||
|
src/idempotency/server/server_channel.lo
|
||||||
|
src/idempotency/server/server_handler.lo
|
||||||
|
src/libserverframe.so
|
||||||
|
src/sf_binlog_writer.lo
|
||||||
|
src/sf_cluster_cfg.lo
|
||||||
|
src/sf_configs.lo
|
||||||
|
src/sf_connection_manager.lo
|
||||||
|
src/sf_func.lo
|
||||||
|
src/sf_global.lo
|
||||||
|
src/sf_nio.lo
|
||||||
|
src/sf_proto.lo
|
||||||
|
src/sf_service.lo
|
||||||
|
src/sf_sharding_htable.lo
|
||||||
|
src/sf_util.lo
|
||||||
|
Copyright: __NO_COPYRIGHT_NOR_LICENSE__
|
||||||
|
License: __NO_COPYRIGHT_NOR_LICENSE__
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Files marked as NO_LICENSE_TEXT_FOUND may be covered by the following
|
||||||
|
# license/copyright files.
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
# License file: LICENSE
|
# License file: LICENSE
|
||||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
Version 3, 19 November 2007
|
Version 3, 19 November 2007
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
usr/lib/libserverframe.so*
|
usr/lib64/libserverframe.so* usr/lib/
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,3 @@ override_dh_auto_build:
|
||||||
override_dh_auto_install:
|
override_dh_auto_install:
|
||||||
./make.sh install
|
./make.sh install
|
||||||
dh_auto_install
|
dh_auto_install
|
||||||
|
|
||||||
.PHONY: override_dh_gencontrol
|
|
||||||
override_dh_gencontrol:
|
|
||||||
dh_gencontrol -- -Tdebian/substvars
|
|
||||||
|
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
libfastcommon:Version=1.0.83
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
%define CommitVersion %(echo $COMMIT_VERSION)
|
%define CommitVersion %(echo $COMMIT_VERSION)
|
||||||
|
|
||||||
Name: libserverframe
|
Name: libserverframe
|
||||||
Version: 1.2.11
|
Version: 1.1.13
|
||||||
Release: 1%{?dist}
|
Release: 1%{?dist}
|
||||||
Summary: network framework library
|
Summary: network framework library
|
||||||
License: AGPL v3.0
|
License: AGPL v3.0
|
||||||
|
|
@ -12,9 +12,9 @@ Source: http://github.com/happyfish100/libserverframe/%{name}-%{version}.tar.gz
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||||
|
|
||||||
BuildRequires: libfastcommon-devel >= 1.0.83
|
BuildRequires: libfastcommon-devel >= 1.0.56
|
||||||
Requires: %__cp %__mv %__chmod %__grep %__mkdir %__install %__id
|
Requires: %__cp %__mv %__chmod %__grep %__mkdir %__install %__id
|
||||||
Requires: libfastcommon >= 1.0.83
|
Requires: libfastcommon >= 1.0.56
|
||||||
|
|
||||||
%description
|
%description
|
||||||
common framework library
|
common framework library
|
||||||
|
|
|
||||||
40
make.sh
40
make.sh
|
|
@ -8,29 +8,15 @@ LIB_VERSION=lib64
|
||||||
DEBUG_FLAG=0
|
DEBUG_FLAG=0
|
||||||
|
|
||||||
if [ -f /usr/include/fastcommon/_os_define.h ]; then
|
if [ -f /usr/include/fastcommon/_os_define.h ]; then
|
||||||
OS_BITS=$(grep -F OS_BITS /usr/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
OS_BITS=$(fgrep OS_BITS /usr/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
||||||
USE_URING=$(grep -F IOEVENT_USE_URING /usr/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
|
||||||
elif [ -f /usr/local/include/fastcommon/_os_define.h ]; then
|
elif [ -f /usr/local/include/fastcommon/_os_define.h ]; then
|
||||||
OS_BITS=$(grep -F OS_BITS /usr/local/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
OS_BITS=$(fgrep OS_BITS /usr/local/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
||||||
USE_URING=$(grep -F IOEVENT_USE_URING /usr/local/include/fastcommon/_os_define.h | awk '{print $NF;}')
|
|
||||||
else
|
else
|
||||||
OS_BITS=64
|
OS_BITS=64
|
||||||
USE_URING=''
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
uname=$(uname)
|
|
||||||
if [ "$OS_BITS" -eq 64 ]; then
|
if [ "$OS_BITS" -eq 64 ]; then
|
||||||
if [ $uname = 'Linux' ]; then
|
LIB_VERSION=lib64
|
||||||
osname=$(cat /etc/os-release | grep -w NAME | awk -F '=' '{print $2;}' | \
|
|
||||||
awk -F '"' '{if (NF==3) {print $2} else {print $1}}' | awk '{print $1}')
|
|
||||||
if [ $osname = 'Ubuntu' -o $osname = 'Debian' ]; then
|
|
||||||
LIB_VERSION=lib
|
|
||||||
else
|
|
||||||
LIB_VERSION=lib64
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
LIB_VERSION=lib
|
|
||||||
fi
|
|
||||||
else
|
else
|
||||||
LIB_VERSION=lib
|
LIB_VERSION=lib
|
||||||
fi
|
fi
|
||||||
|
|
@ -52,9 +38,6 @@ LIBS=''
|
||||||
uname=$(uname)
|
uname=$(uname)
|
||||||
if [ "$uname" = "Linux" ]; then
|
if [ "$uname" = "Linux" ]; then
|
||||||
CFLAGS="$CFLAGS"
|
CFLAGS="$CFLAGS"
|
||||||
if [ -n "$USE_URING" ]; then
|
|
||||||
LIBS="$LIBS -luring"
|
|
||||||
fi
|
|
||||||
elif [ "$uname" = "FreeBSD" ] || [ "$uname" = "Darwin" ]; then
|
elif [ "$uname" = "FreeBSD" ] || [ "$uname" = "Darwin" ]; then
|
||||||
CFLAGS="$CFLAGS"
|
CFLAGS="$CFLAGS"
|
||||||
if [ "$uname" = "Darwin" ]; then
|
if [ "$uname" = "Darwin" ]; then
|
||||||
|
|
@ -83,19 +66,19 @@ elif [ "$uname" = "HP-UX" ]; then
|
||||||
fi
|
fi
|
||||||
elif [ "$uname" = "FreeBSD" ]; then
|
elif [ "$uname" = "FreeBSD" ]; then
|
||||||
if [ -f /usr/lib/libc_r.so ]; then
|
if [ -f /usr/lib/libc_r.so ]; then
|
||||||
line=$(nm -D /usr/lib/libc_r.so | grep -F pthread_create | grep -w T)
|
line=$(nm -D /usr/lib/libc_r.so | grep pthread_create | grep -w T)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
LIBS="$LIBS -lc_r"
|
LIBS="$LIBS -lc_r"
|
||||||
have_pthread=1
|
have_pthread=1
|
||||||
fi
|
fi
|
||||||
elif [ -f /lib64/libc_r.so ]; then
|
elif [ -f /lib64/libc_r.so ]; then
|
||||||
line=$(nm -D /lib64/libc_r.so | grep -F pthread_create | grep -w T)
|
line=$(nm -D /lib64/libc_r.so | grep pthread_create | grep -w T)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
LIBS="$LIBS -lc_r"
|
LIBS="$LIBS -lc_r"
|
||||||
have_pthread=1
|
have_pthread=1
|
||||||
fi
|
fi
|
||||||
elif [ -f /usr/lib64/libc_r.so ]; then
|
elif [ -f /usr/lib64/libc_r.so ]; then
|
||||||
line=$(nm -D /usr/lib64/libc_r.so | grep -F pthread_create | grep -w T)
|
line=$(nm -D /usr/lib64/libc_r.so | grep pthread_create | grep -w T)
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
LIBS="$LIBS -lc_r"
|
LIBS="$LIBS -lc_r"
|
||||||
have_pthread=1
|
have_pthread=1
|
||||||
|
|
@ -104,7 +87,7 @@ elif [ "$uname" = "FreeBSD" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ $have_pthread -eq 0 ] && [ "$uname" = "Linux" ]; then
|
if [ $have_pthread -eq 0 ] && [ "$uname" = "Linux" ]; then
|
||||||
/sbin/ldconfig -p | grep -w libpthread.so > /dev/null
|
/sbin/ldconfig -p | fgrep libpthread.so > /dev/null
|
||||||
if [ $? -eq 0 ]; then
|
if [ $? -eq 0 ]; then
|
||||||
LIBS="$LIBS -lpthread"
|
LIBS="$LIBS -lpthread"
|
||||||
else
|
else
|
||||||
|
|
@ -130,15 +113,8 @@ sed_replace()
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
cd src/include
|
cd src
|
||||||
link=$(readlink sf)
|
|
||||||
if [ $? -ne 0 ] || [ "$link" != '..' -a "$link" != '../' ]; then
|
|
||||||
ln -sf .. sf
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ..
|
|
||||||
cp Makefile.in Makefile
|
cp Makefile.in Makefile
|
||||||
sed_replace "s#\\\$(CC)#gcc#g" Makefile
|
|
||||||
sed_replace "s#\\\$(CFLAGS)#$CFLAGS#g" Makefile
|
sed_replace "s#\\\$(CFLAGS)#$CFLAGS#g" Makefile
|
||||||
sed_replace "s#\\\$(LIBS)#$LIBS#g" Makefile
|
sed_replace "s#\\\$(LIBS)#$LIBS#g" Makefile
|
||||||
sed_replace "s#\\\$(TARGET_PREFIX)#$TARGET_PREFIX#g" Makefile
|
sed_replace "s#\\\$(TARGET_PREFIX)#$TARGET_PREFIX#g" Makefile
|
||||||
|
|
|
||||||
|
|
@ -6,20 +6,16 @@ LIB_PATH = $(LIBS) -lfastcommon
|
||||||
TARGET_LIB = $(TARGET_PREFIX)/$(LIB_VERSION)
|
TARGET_LIB = $(TARGET_PREFIX)/$(LIB_VERSION)
|
||||||
|
|
||||||
TOP_HEADERS = sf_types.h sf_global.h sf_define.h sf_nio.h sf_service.h \
|
TOP_HEADERS = sf_types.h sf_global.h sf_define.h sf_nio.h sf_service.h \
|
||||||
sf_func.h sf_util.h sf_configs.h sf_proto.h sf_cluster_cfg.h \
|
sf_func.h sf_util.h sf_configs.h sf_proto.h sf_binlog_writer.h \
|
||||||
sf_sharding_htable.h sf_connection_manager.h sf_serializer.h \
|
sf_cluster_cfg.h sf_sharding_htable.h sf_connection_manager.h \
|
||||||
sf_binlog_index.h sf_file_writer.h sf_binlog_writer.h \
|
sf_serializer.h sf_binlog_index.h sf_file_writer.h \
|
||||||
sf_ordered_writer.h sf_buffered_writer.h sf_iov.h \
|
sf_ordered_writer.h sf_iov.h
|
||||||
sf_shared_mbuffer.h
|
|
||||||
|
|
||||||
IDEMP_COMMON_HEADER = idempotency/common/idempotency_types.h
|
|
||||||
|
|
||||||
IDEMP_SERVER_HEADER = idempotency/server/server_types.h \
|
IDEMP_SERVER_HEADER = idempotency/server/server_types.h \
|
||||||
idempotency/server/server_channel.h \
|
idempotency/server/server_channel.h \
|
||||||
idempotency/server/request_htable.h \
|
idempotency/server/request_htable.h \
|
||||||
idempotency/server/channel_htable.h \
|
idempotency/server/channel_htable.h \
|
||||||
idempotency/server/server_handler.h \
|
idempotency/server/server_handler.h
|
||||||
idempotency/server/request_metadata.h
|
|
||||||
|
|
||||||
IDEMP_CLIENT_HEADER = idempotency/client/client_types.h \
|
IDEMP_CLIENT_HEADER = idempotency/client/client_types.h \
|
||||||
idempotency/client/receipt_handler.h \
|
idempotency/client/receipt_handler.h \
|
||||||
|
|
@ -30,17 +26,15 @@ ALL_HEADERS = $(TOP_HEADERS) $(IDEMP_SERVER_HEADER) $(IDEMP_CLIENT_HEADER)
|
||||||
|
|
||||||
SHARED_OBJS = sf_nio.lo sf_iov.lo sf_service.lo sf_global.lo \
|
SHARED_OBJS = sf_nio.lo sf_iov.lo sf_service.lo sf_global.lo \
|
||||||
sf_func.lo sf_util.lo sf_configs.lo sf_proto.lo \
|
sf_func.lo sf_util.lo sf_configs.lo sf_proto.lo \
|
||||||
sf_sharding_htable.lo sf_cluster_cfg.lo \
|
sf_binlog_writer.lo sf_sharding_htable.lo \
|
||||||
sf_connection_manager.lo sf_serializer.lo \
|
sf_cluster_cfg.lo sf_connection_manager.lo \
|
||||||
sf_binlog_index.lo sf_file_writer.lo \
|
sf_serializer.lo sf_binlog_index.lo \
|
||||||
sf_binlog_writer.lo sf_ordered_writer.lo \
|
sf_file_writer.lo sf_ordered_writer.lo \
|
||||||
sf_shared_mbuffer.lo \
|
idempotency/server/server_channel.lo \
|
||||||
idempotency/server/server_channel.lo \
|
idempotency/server/request_htable.lo \
|
||||||
idempotency/server/request_htable.lo \
|
idempotency/server/channel_htable.lo \
|
||||||
idempotency/server/channel_htable.lo \
|
idempotency/server/server_handler.lo \
|
||||||
idempotency/server/server_handler.lo \
|
idempotency/client/receipt_handler.lo \
|
||||||
idempotency/server/request_metadata.lo \
|
|
||||||
idempotency/client/receipt_handler.lo \
|
|
||||||
idempotency/client/client_channel.lo
|
idempotency/client/client_channel.lo
|
||||||
|
|
||||||
ALL_OBJS = $(SHARED_OBJS)
|
ALL_OBJS = $(SHARED_OBJS)
|
||||||
|
|
@ -61,18 +55,16 @@ libserverframe.so: $(SHARED_OBJS)
|
||||||
install:
|
install:
|
||||||
mkdir -p $(TARGET_LIB)
|
mkdir -p $(TARGET_LIB)
|
||||||
mkdir -p $(TARGET_PREFIX)/lib
|
mkdir -p $(TARGET_PREFIX)/lib
|
||||||
mkdir -p $(TARGET_PREFIX)/include/sf/idempotency/common
|
|
||||||
mkdir -p $(TARGET_PREFIX)/include/sf/idempotency/server
|
mkdir -p $(TARGET_PREFIX)/include/sf/idempotency/server
|
||||||
mkdir -p $(TARGET_PREFIX)/include/sf/idempotency/client
|
mkdir -p $(TARGET_PREFIX)/include/sf/idempotency/client
|
||||||
|
|
||||||
install -m 755 $(ALL_LIBS) $(TARGET_LIB)
|
install -m 755 $(ALL_LIBS) $(TARGET_LIB)
|
||||||
cp -f $(TOP_HEADERS) $(TARGET_PREFIX)/include/sf
|
cp -f $(TOP_HEADERS) $(TARGET_PREFIX)/include/sf
|
||||||
cp -f $(IDEMP_COMMON_HEADER) $(TARGET_PREFIX)/include/sf/idempotency/common
|
|
||||||
cp -f $(IDEMP_SERVER_HEADER) $(TARGET_PREFIX)/include/sf/idempotency/server
|
cp -f $(IDEMP_SERVER_HEADER) $(TARGET_PREFIX)/include/sf/idempotency/server
|
||||||
cp -f $(IDEMP_CLIENT_HEADER) $(TARGET_PREFIX)/include/sf/idempotency/client
|
cp -f $(IDEMP_CLIENT_HEADER) $(TARGET_PREFIX)/include/sf/idempotency/client
|
||||||
|
|
||||||
@BUILDROOT=$$(echo "$(TARGET_PREFIX)" | grep BUILDROOT); \
|
@BUILDROOT=$$(echo "$(TARGET_PREFIX)" | grep BUILDROOT); \
|
||||||
if [ -z "$$BUILDROOT" ] && [ "$(TARGET_LIB)" != "$(TARGET_PREFIX)/lib" ]; then ln -sf $(TARGET_LIB)/libserverframe.so $(TARGET_PREFIX)/lib/libserverframe.so; fi
|
if [ -z "$$BUILDROOT" ] && [ ! -e $(TARGET_PREFIX)/lib/libserverframe.so ]; then ln -s $(TARGET_LIB)/libserverframe.so $(TARGET_PREFIX)/lib/libserverframe.so; fi
|
||||||
clean:
|
clean:
|
||||||
rm -f $(ALL_OBJS) $(ALL_LIBS) $(ALL_PRGS)
|
rm -f $(ALL_OBJS) $(ALL_LIBS) $(ALL_PRGS)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,11 @@
|
||||||
#include "fastcommon/pthread_func.h"
|
#include "fastcommon/pthread_func.h"
|
||||||
#include "fastcommon/sched_thread.h"
|
#include "fastcommon/sched_thread.h"
|
||||||
#include "fastcommon/fc_queue.h"
|
#include "fastcommon/fc_queue.h"
|
||||||
#include "sf/sf_util.h"
|
#include "../../sf_util.h"
|
||||||
#include "sf/sf_func.h"
|
#include "../../sf_func.h"
|
||||||
#include "sf/sf_nio.h"
|
#include "../../sf_nio.h"
|
||||||
#include "sf/sf_global.h"
|
#include "../../sf_global.h"
|
||||||
#include "sf/sf_service.h"
|
#include "../../sf_service.h"
|
||||||
#include "client_channel.h"
|
#include "client_channel.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -135,7 +135,7 @@ static int idempotency_channel_alloc_init(void *element, void *args)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=init_pthread_lock_cond_pair(&channel->lcp)) != 0) {
|
if ((result=init_pthread_lock_cond_pair(&channel->lc_pair)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,30 +171,17 @@ void client_channel_destroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct fast_task_info *alloc_channel_task(IdempotencyClientChannel
|
static struct fast_task_info *alloc_channel_task(IdempotencyClientChannel
|
||||||
*channel, const uint32_t hash_code, const FCCommunicationType comm_type,
|
*channel, const uint32_t hash_code, const char *server_ip,
|
||||||
const char *server_ip, const uint16_t port, int *err_no)
|
const uint16_t port, int *err_no)
|
||||||
{
|
{
|
||||||
struct fast_task_info *task;
|
struct fast_task_info *task;
|
||||||
SFAddressFamilyHandler *fh;
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
|
|
||||||
if (is_ipv6_addr(server_ip)) {
|
if ((task=sf_alloc_init_task(&g_sf_context, -1)) == NULL) {
|
||||||
fh = g_sf_context.handlers + SF_IPV6_ADDRESS_FAMILY_INDEX;
|
|
||||||
} else {
|
|
||||||
fh = g_sf_context.handlers + SF_IPV4_ADDRESS_FAMILY_INDEX;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (comm_type == fc_comm_type_sock) {
|
|
||||||
handler = fh->handlers + SF_SOCKET_NETWORK_HANDLER_INDEX;
|
|
||||||
} else {
|
|
||||||
handler = fh->handlers + SF_RDMACM_NETWORK_HANDLER_INDEX;
|
|
||||||
}
|
|
||||||
if ((task=sf_alloc_init_task(handler, -1)) == NULL) {
|
|
||||||
*err_no = ENOMEM;
|
*err_no = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
fc_safe_strcpy(task->server_ip, server_ip);
|
snprintf(task->server_ip, sizeof(task->server_ip), "%s", server_ip);
|
||||||
task->port = port;
|
task->port = port;
|
||||||
task->arg = channel;
|
task->arg = channel;
|
||||||
task->thread_data = g_sf_context.thread_data +
|
task->thread_data = g_sf_context.thread_data +
|
||||||
|
|
@ -203,8 +190,7 @@ static struct fast_task_info *alloc_channel_task(IdempotencyClientChannel
|
||||||
channel->last_connect_time = g_current_time;
|
channel->last_connect_time = g_current_time;
|
||||||
if ((*err_no=sf_nio_notify(task, SF_NIO_STAGE_CONNECT)) != 0) {
|
if ((*err_no=sf_nio_notify(task, SF_NIO_STAGE_CONNECT)) != 0) {
|
||||||
channel->in_ioevent = 0; //rollback
|
channel->in_ioevent = 0; //rollback
|
||||||
__sync_sub_and_fetch(&task->reffer_count, 1);
|
sf_release_task(task);
|
||||||
free_queue_push(task);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
return task;
|
return task;
|
||||||
|
|
@ -214,15 +200,6 @@ int idempotency_client_channel_check_reconnect(
|
||||||
IdempotencyClientChannel *channel)
|
IdempotencyClientChannel *channel)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
struct fast_task_info *task;
|
|
||||||
task = channel->task;
|
|
||||||
if (SF_CTX->use_io_uring && FC_ATOMIC_GET(task->reffer_count) > 1) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!__sync_bool_compare_and_swap(&channel->in_ioevent, 0, 1)) {
|
if (!__sync_bool_compare_and_swap(&channel->in_ioevent, 0, 1)) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -233,16 +210,11 @@ int idempotency_client_channel_check_reconnect(
|
||||||
channel->last_connect_time = g_current_time;
|
channel->last_connect_time = g_current_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FC_LOG_BY_LEVEL(LOG_DEBUG)) {
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
format_ip_address(channel->task->server_ip, formatted_ip);
|
"trigger connect to server %s:%u",
|
||||||
logDebug("file: "__FILE__", line: %d, "
|
__LINE__, channel->task->server_ip,
|
||||||
"trigger connect to server %s:%u", __LINE__,
|
channel->task->port);
|
||||||
formatted_ip, channel->task->port);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (channel->task->event.fd >= 0) {
|
|
||||||
channel->task->handler->close_connection(channel->task);
|
|
||||||
}
|
|
||||||
__sync_bool_compare_and_swap(&channel->task->canceled, 1, 0);
|
__sync_bool_compare_and_swap(&channel->task->canceled, 1, 0);
|
||||||
if ((result=sf_nio_notify(channel->task, SF_NIO_STAGE_CONNECT)) == 0) {
|
if ((result=sf_nio_notify(channel->task, SF_NIO_STAGE_CONNECT)) == 0) {
|
||||||
channel->last_connect_time = g_current_time;
|
channel->last_connect_time = g_current_time;
|
||||||
|
|
@ -254,8 +226,8 @@ int idempotency_client_channel_check_reconnect(
|
||||||
}
|
}
|
||||||
|
|
||||||
struct idempotency_client_channel *idempotency_client_channel_get(
|
struct idempotency_client_channel *idempotency_client_channel_get(
|
||||||
const FCCommunicationType comm_type, const char *server_ip,
|
const char *server_ip, const uint16_t server_port,
|
||||||
const uint16_t server_port, const int timeout, int *err_no)
|
const int timeout, int *err_no)
|
||||||
{
|
{
|
||||||
int r;
|
int r;
|
||||||
int key_len;
|
int key_len;
|
||||||
|
|
@ -267,10 +239,7 @@ struct idempotency_client_channel *idempotency_client_channel_get(
|
||||||
IdempotencyClientChannel *current;
|
IdempotencyClientChannel *current;
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
|
|
||||||
key_len = strlen(server_ip);
|
key_len = snprintf(key, sizeof(key), "%s_%u", server_ip, server_port);
|
||||||
memcpy(key, server_ip, key_len);
|
|
||||||
*(key + key_len++) = '-';
|
|
||||||
key_len += fc_itoa(server_port, key + key_len);
|
|
||||||
hash_code = fc_simple_hash(key, key_len);
|
hash_code = fc_simple_hash(key, key_len);
|
||||||
bucket = channel_context.htable.buckets +
|
bucket = channel_context.htable.buckets +
|
||||||
hash_code % channel_context.htable.capacity;
|
hash_code % channel_context.htable.capacity;
|
||||||
|
|
@ -308,8 +277,8 @@ struct idempotency_client_channel *idempotency_client_channel_get(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
channel->task = alloc_channel_task(channel, hash_code,
|
channel->task = alloc_channel_task(channel,
|
||||||
comm_type, server_ip, server_port, err_no);
|
hash_code, server_ip, server_port, err_no);
|
||||||
if (channel->task == NULL) {
|
if (channel->task == NULL) {
|
||||||
fast_mblock_free_object(&channel_context.
|
fast_mblock_free_object(&channel_context.
|
||||||
channel_allocator, channel);
|
channel_allocator, channel);
|
||||||
|
|
@ -354,8 +323,8 @@ int idempotency_client_channel_push(struct idempotency_client_channel *channel,
|
||||||
receipt->req_id = req_id;
|
receipt->req_id = req_id;
|
||||||
fc_queue_push_ex(&channel->queue, receipt, ¬ify);
|
fc_queue_push_ex(&channel->queue, receipt, ¬ify);
|
||||||
if (notify) {
|
if (notify) {
|
||||||
if (FC_ATOMIC_GET(channel->in_ioevent)) {
|
if (__sync_add_and_fetch(&channel->in_ioevent, 0)) {
|
||||||
if (FC_ATOMIC_GET(channel->established)) {
|
if (__sync_add_and_fetch(&channel->established, 0)) {
|
||||||
sf_nio_notify(channel->task, SF_NIO_STAGE_CONTINUE);
|
sf_nio_notify(channel->task, SF_NIO_STAGE_CONTINUE);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -22,7 +22,6 @@
|
||||||
#include "fastcommon/pthread_func.h"
|
#include "fastcommon/pthread_func.h"
|
||||||
#include "fastcommon/sched_thread.h"
|
#include "fastcommon/sched_thread.h"
|
||||||
#include "fastcommon/fc_atomic.h"
|
#include "fastcommon/fc_atomic.h"
|
||||||
#include "sf/sf_types.h"
|
|
||||||
#include "client_types.h"
|
#include "client_types.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -41,14 +40,13 @@ void idempotency_client_channel_config_to_string_ex(
|
||||||
char *output, const int size, const bool add_comma);
|
char *output, const int size, const bool add_comma);
|
||||||
|
|
||||||
struct idempotency_client_channel *idempotency_client_channel_get(
|
struct idempotency_client_channel *idempotency_client_channel_get(
|
||||||
const FCCommunicationType comm_type, const char *server_ip,
|
const char *server_ip, const uint16_t server_port,
|
||||||
const uint16_t server_port, const int timeout, int *err_no);
|
const int timeout, int *err_no);
|
||||||
|
|
||||||
static inline uint64_t idempotency_client_channel_next_seq_id(
|
static inline uint64_t idempotency_client_channel_next_seq_id(
|
||||||
struct idempotency_client_channel *channel)
|
struct idempotency_client_channel *channel)
|
||||||
{
|
{
|
||||||
return SF_IDEMPOTENCY_NEXT_REQ_ID(channel->server_id,
|
return __sync_add_and_fetch(&channel->next_req_id, 1);
|
||||||
channel->id, FC_ATOMIC_INC(channel->next_seq));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int idempotency_client_channel_push(struct idempotency_client_channel *channel,
|
int idempotency_client_channel_push(struct idempotency_client_channel *channel,
|
||||||
|
|
@ -76,28 +74,13 @@ static inline void idempotency_client_channel_set_id_key(
|
||||||
static inline int idempotency_client_channel_check_wait_ex(
|
static inline int idempotency_client_channel_check_wait_ex(
|
||||||
struct idempotency_client_channel *channel, const int timeout)
|
struct idempotency_client_channel *channel, const int timeout)
|
||||||
{
|
{
|
||||||
if (FC_ATOMIC_GET(channel->established)) {
|
if (__sync_add_and_fetch(&channel->established, 0)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
idempotency_client_channel_check_reconnect(channel);
|
idempotency_client_channel_check_reconnect(channel);
|
||||||
lcp_timedwait_sec(&channel->lcp, timeout);
|
lcp_timedwait_sec(&channel->lc_pair, timeout);
|
||||||
if (FC_ATOMIC_GET(channel->established)) {
|
return __sync_add_and_fetch(&channel->established, 0) ? 0 : ETIMEDOUT;
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
format_ip_address(channel->task->server_ip, formatted_ip);
|
|
||||||
logInfo("file: "__FILE__", line: %d, "
|
|
||||||
"channel_check fail, server %s:%u, in_ioevent: %d, "
|
|
||||||
"canceled: %d, req count: %"PRId64, __LINE__,
|
|
||||||
formatted_ip, channel->task->port,
|
|
||||||
__sync_add_and_fetch(&channel->in_ioevent, 0),
|
|
||||||
__sync_add_and_fetch(&channel->task->canceled, 0),
|
|
||||||
channel->task->req_count);
|
|
||||||
*/
|
|
||||||
return ETIMEDOUT;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#include "fastcommon/fast_mblock.h"
|
#include "fastcommon/fast_mblock.h"
|
||||||
#include "fastcommon/fc_list.h"
|
#include "fastcommon/fc_list.h"
|
||||||
#include "fastcommon/fc_queue.h"
|
#include "fastcommon/fc_queue.h"
|
||||||
#include "sf/idempotency/common/idempotency_types.h"
|
|
||||||
|
|
||||||
typedef struct idempotency_client_config {
|
typedef struct idempotency_client_config {
|
||||||
bool enabled;
|
bool enabled;
|
||||||
|
|
@ -41,12 +40,11 @@ typedef struct idempotency_client_channel {
|
||||||
volatile char in_ioevent;
|
volatile char in_ioevent;
|
||||||
volatile char established;
|
volatile char established;
|
||||||
int buffer_size; //the min task size of the server and mine
|
int buffer_size; //the min task size of the server and mine
|
||||||
uint32_t server_id;
|
|
||||||
volatile uint32_t next_seq;
|
|
||||||
time_t last_connect_time; //for connect frequency control
|
time_t last_connect_time; //for connect frequency control
|
||||||
time_t last_pkg_time; //last communication time
|
time_t last_pkg_time; //last communication time
|
||||||
time_t last_report_time; //last report time for rpc receipt
|
time_t last_report_time; //last report time for rpc receipt
|
||||||
pthread_lock_cond_pair_t lcp; //for channel valid check and notify
|
pthread_lock_cond_pair_t lc_pair; //for channel valid check and notify
|
||||||
|
volatile uint64_t next_req_id;
|
||||||
struct fast_mblock_man receipt_allocator;
|
struct fast_mblock_man receipt_allocator;
|
||||||
struct fast_task_info *task;
|
struct fast_task_info *task;
|
||||||
struct fc_queue queue;
|
struct fc_queue queue;
|
||||||
|
|
@ -63,14 +61,6 @@ typedef struct idempotency_receipt_thread_context {
|
||||||
} last_check_times;
|
} last_check_times;
|
||||||
} IdempotencyReceiptThreadContext;
|
} IdempotencyReceiptThreadContext;
|
||||||
|
|
||||||
typedef struct idempotency_receipt_global_vars {
|
|
||||||
struct {
|
|
||||||
int task_padding_size;
|
|
||||||
sf_init_connection_callback init_connection;
|
|
||||||
} rdma;
|
|
||||||
IdempotencyReceiptThreadContext *thread_contexts;
|
|
||||||
} IdempotencyReceiptGlobalVars;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -41,35 +41,23 @@
|
||||||
#include "client_channel.h"
|
#include "client_channel.h"
|
||||||
#include "receipt_handler.h"
|
#include "receipt_handler.h"
|
||||||
|
|
||||||
static IdempotencyReceiptGlobalVars receipt_global_vars;
|
static IdempotencyReceiptThreadContext *receipt_thread_contexts = NULL;
|
||||||
|
|
||||||
#define RECEIPT_THREAD_CONTEXTS receipt_global_vars.thread_contexts
|
static int receipt_init_task(struct fast_task_info *task)
|
||||||
#define TASK_PADDING_SIZE receipt_global_vars.rdma.task_padding_size
|
|
||||||
#define RDMA_INIT_CONNECTION receipt_global_vars.rdma.init_connection
|
|
||||||
|
|
||||||
static int receipt_init_task(struct fast_task_info *task, void *arg)
|
|
||||||
{
|
{
|
||||||
#if IOEVENT_USE_URING
|
task->connect_timeout = SF_G_CONNECT_TIMEOUT; //for client side
|
||||||
FC_URING_IS_CLIENT(task) = true;
|
task->network_timeout = SF_G_NETWORK_TIMEOUT;
|
||||||
#endif
|
return 0;
|
||||||
|
|
||||||
if (RDMA_INIT_CONNECTION != NULL) {
|
|
||||||
return RDMA_INIT_CONNECTION(task, arg);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int receipt_recv_timeout_callback(struct fast_task_info *task)
|
static int receipt_recv_timeout_callback(struct fast_task_info *task)
|
||||||
{
|
{
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
if (SF_NIO_TASK_STAGE_FETCH(task) == SF_NIO_STAGE_CONNECT) {
|
if (SF_NIO_TASK_STAGE_FETCH(task) == SF_NIO_STAGE_CONNECT) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"connect to server %s:%u timeout",
|
"connect to server %s:%u timeout",
|
||||||
__LINE__, formatted_ip, task->port);
|
__LINE__, task->server_ip, task->port);
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,13 +65,11 @@ static int receipt_recv_timeout_callback(struct fast_task_info *task)
|
||||||
if (channel->waiting_resp_qinfo.head != NULL) {
|
if (channel->waiting_resp_qinfo.head != NULL) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"waiting receipt response from server %s:%u timeout",
|
"waiting receipt response from server %s:%u timeout",
|
||||||
__LINE__, formatted_ip, task->port);
|
__LINE__, task->server_ip, task->port);
|
||||||
} else {
|
} else {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s server %s:%u timeout, channel established: %d",
|
"communication with server %s:%u timeout",
|
||||||
__LINE__, task->nio_stages.current == SF_NIO_STAGE_SEND ?
|
__LINE__, task->server_ip, task->port);
|
||||||
"send to" : "recv from", formatted_ip, task->port,
|
|
||||||
FC_ATOMIC_GET(channel->established));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ETIMEDOUT;
|
return ETIMEDOUT;
|
||||||
|
|
@ -92,27 +78,22 @@ static int receipt_recv_timeout_callback(struct fast_task_info *task)
|
||||||
static void receipt_task_finish_cleanup(struct fast_task_info *task)
|
static void receipt_task_finish_cleanup(struct fast_task_info *task)
|
||||||
{
|
{
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
if (task->event.fd >= 0) {
|
if (task->event.fd >= 0) {
|
||||||
sf_task_detach_thread(task);
|
sf_task_detach_thread(task);
|
||||||
|
close(task->event.fd);
|
||||||
|
task->event.fd = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_nio_reset_task_length(task);
|
|
||||||
task->req_count = 0;
|
|
||||||
task->pending_send_count = 0;
|
|
||||||
|
|
||||||
channel = (IdempotencyClientChannel *)task->arg;
|
channel = (IdempotencyClientChannel *)task->arg;
|
||||||
|
|
||||||
fc_list_del_init(&channel->dlink);
|
fc_list_del_init(&channel->dlink);
|
||||||
__sync_bool_compare_and_swap(&channel->established, 1, 0);
|
__sync_bool_compare_and_swap(&channel->established, 1, 0);
|
||||||
__sync_bool_compare_and_swap(&channel->in_ioevent, 1, 0);
|
__sync_bool_compare_and_swap(&channel->in_ioevent, 1, 0);
|
||||||
|
|
||||||
if (FC_LOG_BY_LEVEL(LOG_DEBUG)) {
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
"receipt task for server %s:%u exit",
|
||||||
logDebug("file: "__FILE__", line: %d, "
|
__LINE__, task->server_ip, task->port);
|
||||||
"receipt task for server %s:%u exit",
|
|
||||||
__LINE__, formatted_ip, task->port);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setup_channel_request(struct fast_task_info *task)
|
static void setup_channel_request(struct fast_task_info *task)
|
||||||
|
|
@ -122,15 +103,14 @@ static void setup_channel_request(struct fast_task_info *task)
|
||||||
SFProtoSetupChannelReq *req;
|
SFProtoSetupChannelReq *req;
|
||||||
|
|
||||||
channel = (IdempotencyClientChannel *)task->arg;
|
channel = (IdempotencyClientChannel *)task->arg;
|
||||||
header = (SFCommonProtoHeader *)task->send.ptr->data;
|
header = (SFCommonProtoHeader *)task->data;
|
||||||
req = (SFProtoSetupChannelReq *)(header + 1);
|
req = (SFProtoSetupChannelReq *)(header + 1);
|
||||||
int2buff(__sync_add_and_fetch(&channel->id, 0), req->channel_id);
|
int2buff(__sync_add_and_fetch(&channel->id, 0), req->channel_id);
|
||||||
int2buff(__sync_add_and_fetch(&channel->key, 0), req->key);
|
int2buff(__sync_add_and_fetch(&channel->key, 0), req->key);
|
||||||
|
|
||||||
SF_PROTO_SET_HEADER(header, SF_SERVICE_PROTO_SETUP_CHANNEL_REQ,
|
SF_PROTO_SET_HEADER(header, SF_SERVICE_PROTO_SETUP_CHANNEL_REQ,
|
||||||
sizeof(SFProtoSetupChannelReq));
|
sizeof(SFProtoSetupChannelReq));
|
||||||
task->send.ptr->length = sizeof(SFCommonProtoHeader) +
|
task->length = sizeof(SFCommonProtoHeader) + sizeof(SFProtoSetupChannelReq);
|
||||||
sizeof(SFProtoSetupChannelReq);
|
|
||||||
sf_send_add_event(task);
|
sf_send_add_event(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -157,10 +137,10 @@ static int check_report_req_receipt(struct fast_task_info *task)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = (SFCommonProtoHeader *)task->send.ptr->data;
|
header = (SFCommonProtoHeader *)task->data;
|
||||||
rheader = (SFProtoReportReqReceiptHeader *)(header + 1);
|
rheader = (SFProtoReportReqReceiptHeader *)(header + 1);
|
||||||
rbody = rstart = (SFProtoReportReqReceiptBody *)(rheader + 1);
|
rbody = rstart = (SFProtoReportReqReceiptBody *)(rheader + 1);
|
||||||
buff_end = task->send.ptr->data + channel->buffer_size;
|
buff_end = task->data + channel->buffer_size;
|
||||||
last = NULL;
|
last = NULL;
|
||||||
receipt = channel->waiting_resp_qinfo.head;
|
receipt = channel->waiting_resp_qinfo.head;
|
||||||
do {
|
do {
|
||||||
|
|
@ -190,9 +170,8 @@ static int check_report_req_receipt(struct fast_task_info *task)
|
||||||
|
|
||||||
count = rbody - rstart;
|
count = rbody - rstart;
|
||||||
int2buff(count, rheader->count);
|
int2buff(count, rheader->count);
|
||||||
task->send.ptr->length = (char *)rbody - task->send.ptr->data;
|
task->length = (char *)rbody - task->data;
|
||||||
int2buff(task->send.ptr->length - sizeof(SFCommonProtoHeader),
|
int2buff(task->length - sizeof(SFCommonProtoHeader), header->body_len);
|
||||||
header->body_len);
|
|
||||||
header->cmd = SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_REQ;
|
header->cmd = SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_REQ;
|
||||||
sf_send_add_event(task);
|
sf_send_add_event(task);
|
||||||
return count;
|
return count;
|
||||||
|
|
@ -206,18 +185,18 @@ static void close_channel_request(struct fast_task_info *task)
|
||||||
channel = (IdempotencyClientChannel *)task->arg;
|
channel = (IdempotencyClientChannel *)task->arg;
|
||||||
idempotency_client_channel_set_id_key(channel, 0, 0);
|
idempotency_client_channel_set_id_key(channel, 0, 0);
|
||||||
|
|
||||||
header = (SFCommonProtoHeader *)task->send.ptr->data;
|
header = (SFCommonProtoHeader *)task->data;
|
||||||
SF_PROTO_SET_HEADER(header, SF_SERVICE_PROTO_CLOSE_CHANNEL_REQ, 0);
|
SF_PROTO_SET_HEADER(header, SF_SERVICE_PROTO_CLOSE_CHANNEL_REQ, 0);
|
||||||
task->send.ptr->length = sizeof(SFCommonProtoHeader);
|
task->length = sizeof(SFCommonProtoHeader);
|
||||||
sf_send_add_event(task);
|
sf_send_add_event(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void active_test_request(struct fast_task_info *task)
|
static void active_test_request(struct fast_task_info *task)
|
||||||
{
|
{
|
||||||
SFCommonProtoHeader *header;
|
SFCommonProtoHeader *header;
|
||||||
header = (SFCommonProtoHeader *)task->send.ptr->data;
|
header = (SFCommonProtoHeader *)task->data;
|
||||||
SF_PROTO_SET_HEADER(header, SF_PROTO_ACTIVE_TEST_REQ, 0);
|
SF_PROTO_SET_HEADER(header, SF_PROTO_ACTIVE_TEST_REQ, 0);
|
||||||
task->send.ptr->length = sizeof(SFCommonProtoHeader);
|
task->length = sizeof(SFCommonProtoHeader);
|
||||||
sf_send_add_event(task);
|
sf_send_add_event(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -245,22 +224,17 @@ static void report_req_receipt_request(struct fast_task_info *task,
|
||||||
if (update_lru) {
|
if (update_lru) {
|
||||||
update_lru_chain(task);
|
update_lru_chain(task);
|
||||||
}
|
}
|
||||||
task->pending_send_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int receipt_expect_body_length(struct fast_task_info *task,
|
static inline int receipt_expect_body_length(struct fast_task_info *task,
|
||||||
const int expect_body_len)
|
const int expect_body_len)
|
||||||
{
|
{
|
||||||
int body_len;
|
if ((int)(task->length - sizeof(SFCommonProtoHeader)) != expect_body_len) {
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
body_len = task->recv.ptr->length - sizeof(SFCommonProtoHeader);
|
|
||||||
if (body_len != expect_body_len) {
|
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"server %s:%u, response body length: %d != %d", __LINE__,
|
"server %s:%u, response body length: %d != %d",
|
||||||
formatted_ip, task->port, body_len, expect_body_len);
|
__LINE__, task->server_ip, task->port, (int)(task->length -
|
||||||
|
sizeof(SFCommonProtoHeader)), expect_body_len);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -273,7 +247,6 @@ static int deal_setup_channel_response(struct fast_task_info *task)
|
||||||
IdempotencyReceiptThreadContext *thread_ctx;
|
IdempotencyReceiptThreadContext *thread_ctx;
|
||||||
SFProtoSetupChannelResp *resp;
|
SFProtoSetupChannelResp *resp;
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
int channel_id;
|
int channel_id;
|
||||||
int channel_key;
|
int channel_key;
|
||||||
int buffer_size;
|
int buffer_size;
|
||||||
|
|
@ -285,30 +258,28 @@ static int deal_setup_channel_response(struct fast_task_info *task)
|
||||||
}
|
}
|
||||||
|
|
||||||
channel = (IdempotencyClientChannel *)task->arg;
|
channel = (IdempotencyClientChannel *)task->arg;
|
||||||
if (FC_ATOMIC_GET(channel->established)) {
|
if (__sync_add_and_fetch(&channel->established, 0)) {
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"response from server %s:%u, unexpected cmd: "
|
"response from server %s:%u, unexpected cmd: "
|
||||||
"SETUP_CHANNEL_RESP, ignore it!",
|
"SETUP_CHANNEL_RESP, ignore it!",
|
||||||
__LINE__, formatted_ip, task->port);
|
__LINE__, task->server_ip, task->port);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
resp = (SFProtoSetupChannelResp *)SF_PROTO_RECV_BODY(task);
|
resp = (SFProtoSetupChannelResp *)(task->data + sizeof(SFCommonProtoHeader));
|
||||||
channel_id = buff2int(resp->channel_id);
|
channel_id = buff2int(resp->channel_id);
|
||||||
channel_key = buff2int(resp->key);
|
channel_key = buff2int(resp->key);
|
||||||
buffer_size = buff2int(resp->buffer_size);
|
buffer_size = buff2int(resp->buffer_size);
|
||||||
channel->server_id = buff2int(resp->server_id);
|
|
||||||
idempotency_client_channel_set_id_key(channel, channel_id, channel_key);
|
idempotency_client_channel_set_id_key(channel, channel_id, channel_key);
|
||||||
if (__sync_bool_compare_and_swap(&channel->established, 0, 1)) {
|
if (__sync_bool_compare_and_swap(&channel->established, 0, 1)) {
|
||||||
thread_ctx = (IdempotencyReceiptThreadContext *)task->thread_data->arg;
|
thread_ctx = (IdempotencyReceiptThreadContext *)task->thread_data->arg;
|
||||||
fc_list_add_tail(&channel->dlink, &thread_ctx->head);
|
fc_list_add_tail(&channel->dlink, &thread_ctx->head);
|
||||||
}
|
}
|
||||||
channel->buffer_size = FC_MIN(buffer_size, task->send.ptr->size);
|
channel->buffer_size = FC_MIN(buffer_size, task->size);
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&channel->lcp.lock);
|
PTHREAD_MUTEX_LOCK(&channel->lc_pair.lock);
|
||||||
pthread_cond_broadcast(&channel->lcp.cond);
|
pthread_cond_broadcast(&channel->lc_pair.cond);
|
||||||
PTHREAD_MUTEX_UNLOCK(&channel->lcp.lock);
|
PTHREAD_MUTEX_UNLOCK(&channel->lc_pair.lock);
|
||||||
|
|
||||||
if (channel->waiting_resp_qinfo.head != NULL) {
|
if (channel->waiting_resp_qinfo.head != NULL) {
|
||||||
bool notify;
|
bool notify;
|
||||||
|
|
@ -327,7 +298,6 @@ static inline int deal_report_req_receipt_response(struct fast_task_info *task)
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
IdempotencyClientReceipt *current;
|
IdempotencyClientReceipt *current;
|
||||||
IdempotencyClientReceipt *deleted;
|
IdempotencyClientReceipt *deleted;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
if ((result=receipt_expect_body_length(task, 0)) != 0) {
|
if ((result=receipt_expect_body_length(task, 0)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -335,15 +305,13 @@ static inline int deal_report_req_receipt_response(struct fast_task_info *task)
|
||||||
|
|
||||||
channel = (IdempotencyClientChannel *)task->arg;
|
channel = (IdempotencyClientChannel *)task->arg;
|
||||||
if (channel->waiting_resp_qinfo.head == NULL) {
|
if (channel->waiting_resp_qinfo.head == NULL) {
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"response from server %s:%u, unexpect cmd: "
|
"response from server %s:%u, unexpect cmd: "
|
||||||
"REPORT_REQ_RECEIPT_RESP", __LINE__,
|
"REPORT_REQ_RECEIPT_RESP", __LINE__,
|
||||||
formatted_ip, task->port);
|
task->server_ip, task->port);
|
||||||
return EINVAL;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
task->pending_send_count--;
|
|
||||||
current = channel->waiting_resp_qinfo.head;
|
current = channel->waiting_resp_qinfo.head;
|
||||||
do {
|
do {
|
||||||
deleted = current;
|
deleted = current;
|
||||||
|
|
@ -360,46 +328,40 @@ static inline int deal_report_req_receipt_response(struct fast_task_info *task)
|
||||||
static int receipt_deal_task(struct fast_task_info *task, const int stage)
|
static int receipt_deal_task(struct fast_task_info *task, const int stage)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
SFCommonProtoHeader *header;
|
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (stage == SF_NIO_STAGE_HANDSHAKE) {
|
if (stage == SF_NIO_STAGE_HANDSHAKE) {
|
||||||
setup_channel_request(task);
|
setup_channel_request(task);
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
} else if (stage == SF_NIO_STAGE_CONTINUE) {
|
} else if (stage == SF_NIO_STAGE_CONTINUE && task->length == 0) {
|
||||||
if (task->pending_send_count == 0) {
|
if (((IdempotencyClientChannel *)task->arg)->established) {
|
||||||
if (((IdempotencyClientChannel *)task->arg)->established) {
|
report_req_receipt_request(task, true);
|
||||||
report_req_receipt_request(task, true);
|
} else {
|
||||||
} else if (task->req_count > 0) {
|
sf_set_read_event(task); //trigger read event
|
||||||
sf_set_read_event(task); //trigger read event
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
header = (SFCommonProtoHeader *)task->recv.ptr->data;
|
result = buff2short(((SFCommonProtoHeader *)task->data)->status);
|
||||||
result = buff2short(header->status);
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
int msg_len;
|
int msg_len;
|
||||||
char *message;
|
char *message;
|
||||||
|
|
||||||
msg_len = SF_RECV_BODY_LENGTH(task);
|
msg_len = task->length - sizeof(SFCommonProtoHeader);
|
||||||
message = SF_PROTO_RECV_BODY(task);
|
message = task->data + sizeof(SFCommonProtoHeader);
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"response from server %s:%u, cmd: %d (%s), "
|
"response from server %s:%u, cmd: %d (%s), "
|
||||||
"status: %d, error info: %.*s", __LINE__,
|
"status: %d, error info: %.*s",
|
||||||
formatted_ip, task->port, header->cmd,
|
__LINE__, task->server_ip, task->port,
|
||||||
sf_get_cmd_caption(header->cmd),
|
((SFCommonProtoHeader *)task->data)->cmd,
|
||||||
|
sf_get_cmd_caption(((SFCommonProtoHeader *)task->data)->cmd),
|
||||||
result, msg_len, message);
|
result, msg_len, message);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (header->cmd) {
|
switch (((SFCommonProtoHeader *)task->data)->cmd) {
|
||||||
case SF_SERVICE_PROTO_SETUP_CHANNEL_RESP:
|
case SF_SERVICE_PROTO_SETUP_CHANNEL_RESP:
|
||||||
result = deal_setup_channel_response(task);
|
result = deal_setup_channel_response(task);
|
||||||
break;
|
break;
|
||||||
|
|
@ -407,35 +369,28 @@ static int receipt_deal_task(struct fast_task_info *task, const int stage)
|
||||||
result = deal_report_req_receipt_response(task);
|
result = deal_report_req_receipt_response(task);
|
||||||
break;
|
break;
|
||||||
case SF_PROTO_ACTIVE_TEST_RESP:
|
case SF_PROTO_ACTIVE_TEST_RESP:
|
||||||
task->pending_send_count--;
|
|
||||||
result = 0;
|
result = 0;
|
||||||
break;
|
break;
|
||||||
case SF_SERVICE_PROTO_CLOSE_CHANNEL_RESP:
|
case SF_SERVICE_PROTO_CLOSE_CHANNEL_RESP:
|
||||||
result = ECONNRESET; //force to close socket
|
result = ECONNRESET; //force to close socket
|
||||||
if (FC_LOG_BY_LEVEL(LOG_DEBUG)) {
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
"close channel to server %s:%u !!!",
|
||||||
logDebug("file: "__FILE__", line: %d, "
|
__LINE__, task->server_ip, task->port);
|
||||||
"close channel to server %s:%u !!!",
|
|
||||||
__LINE__, formatted_ip, task->port);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
format_ip_address(task->server_ip, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"response from server %s:%u, unexpect cmd: %d (%s)",
|
"response from server %s:%u, unexpect cmd: %d (%s)",
|
||||||
__LINE__, formatted_ip, task->port, header->cmd,
|
__LINE__, task->server_ip, task->port,
|
||||||
sf_get_cmd_caption(header->cmd));
|
((SFCommonProtoHeader *)task->data)->cmd,
|
||||||
|
sf_get_cmd_caption(((SFCommonProtoHeader *)task->data)->cmd));
|
||||||
result = EINVAL;
|
result = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
update_lru_chain(task);
|
update_lru_chain(task);
|
||||||
task->recv.ptr->length = 0;
|
task->offset = task->length = 0;
|
||||||
task->recv.ptr->offset = 0;
|
report_req_receipt_request(task, false);
|
||||||
if (task->pending_send_count == 0) {
|
|
||||||
report_req_receipt_request(task, false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
||||||
|
|
@ -455,10 +410,9 @@ static void receipt_thread_check_heartbeat(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel->task->pending_send_count == 0) {
|
if (sf_nio_task_is_idle(channel->task)) {
|
||||||
channel->last_pkg_time = g_current_time;
|
channel->last_pkg_time = g_current_time;
|
||||||
active_test_request(channel->task);
|
active_test_request(channel->task);
|
||||||
channel->task->pending_send_count++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -468,22 +422,18 @@ static void receipt_thread_close_idle_channel(
|
||||||
{
|
{
|
||||||
IdempotencyClientChannel *channel;
|
IdempotencyClientChannel *channel;
|
||||||
IdempotencyClientChannel *tmp;
|
IdempotencyClientChannel *tmp;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
fc_list_for_each_entry_safe(channel, tmp, &thread_ctx->head, dlink) {
|
fc_list_for_each_entry_safe(channel, tmp, &thread_ctx->head, dlink) {
|
||||||
if (channel->task->pending_send_count > 0) {
|
if (!sf_nio_task_is_idle(channel->task)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_current_time - channel->last_report_time >
|
if (g_current_time - channel->last_report_time >
|
||||||
g_idempotency_client_cfg.channel_max_idle_time)
|
g_idempotency_client_cfg.channel_max_idle_time)
|
||||||
{
|
{
|
||||||
if (FC_LOG_BY_LEVEL(LOG_DEBUG)) {
|
logDebug("file: "__FILE__", line: %d, "
|
||||||
format_ip_address(channel->task->server_ip, formatted_ip);
|
"close channel to server %s:%u because idle too long",
|
||||||
logDebug("file: "__FILE__", line: %d, "
|
__LINE__, channel->task->server_ip, channel->task->port);
|
||||||
"close channel to server %s:%u because idle too long",
|
|
||||||
__LINE__, formatted_ip, channel->task->port);
|
|
||||||
}
|
|
||||||
close_channel_request(channel->task);
|
close_channel_request(channel->task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -514,61 +464,40 @@ static void *receipt_alloc_thread_extra_data(const int thread_index)
|
||||||
{
|
{
|
||||||
IdempotencyReceiptThreadContext *ctx;
|
IdempotencyReceiptThreadContext *ctx;
|
||||||
|
|
||||||
ctx = RECEIPT_THREAD_CONTEXTS + thread_index;
|
ctx = receipt_thread_contexts + thread_index;
|
||||||
FC_INIT_LIST_HEAD(&ctx->head);
|
FC_INIT_LIST_HEAD(&ctx->head);
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int do_init(FCAddressPtrArray *address_array)
|
static int do_init()
|
||||||
{
|
{
|
||||||
const int task_arg_size = 0;
|
|
||||||
const bool double_buffers = false;
|
|
||||||
const bool need_shrink_task_buffer = false;
|
|
||||||
const bool explicit_post_recv = false;
|
|
||||||
int result;
|
|
||||||
int bytes;
|
int bytes;
|
||||||
SFNetworkHandler *rdma_handler;
|
|
||||||
struct ibv_pd *pd;
|
|
||||||
|
|
||||||
bytes = sizeof(IdempotencyReceiptThreadContext) * SF_G_WORK_THREADS;
|
bytes = sizeof(IdempotencyReceiptThreadContext) * SF_G_WORK_THREADS;
|
||||||
RECEIPT_THREAD_CONTEXTS = (IdempotencyReceiptThreadContext *)
|
receipt_thread_contexts = (IdempotencyReceiptThreadContext *)
|
||||||
fc_malloc(bytes);
|
fc_malloc(bytes);
|
||||||
if (RECEIPT_THREAD_CONTEXTS == NULL) {
|
if (receipt_thread_contexts == NULL) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
memset(RECEIPT_THREAD_CONTEXTS, 0, bytes);
|
memset(receipt_thread_contexts, 0, bytes);
|
||||||
|
|
||||||
if ((rdma_handler=sf_get_rdma_network_handler(&g_sf_context)) != NULL) {
|
|
||||||
if ((result=sf_alloc_rdma_pd(&g_sf_context, address_array)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
TASK_PADDING_SIZE = rdma_handler->get_connection_size();
|
|
||||||
RDMA_INIT_CONNECTION = rdma_handler->init_connection;
|
|
||||||
pd = rdma_handler->pd;
|
|
||||||
} else {
|
|
||||||
TASK_PADDING_SIZE = 0;
|
|
||||||
RDMA_INIT_CONNECTION = NULL;
|
|
||||||
pd = NULL;
|
|
||||||
}
|
|
||||||
return sf_service_init_ex2(&g_sf_context, "idemp-receipt",
|
return sf_service_init_ex2(&g_sf_context, "idemp-receipt",
|
||||||
receipt_alloc_thread_extra_data, receipt_thread_loop_callback,
|
receipt_alloc_thread_extra_data, receipt_thread_loop_callback,
|
||||||
NULL, sf_proto_set_body_length, NULL, NULL, receipt_deal_task,
|
NULL, sf_proto_set_body_length, receipt_deal_task,
|
||||||
receipt_task_finish_cleanup, receipt_recv_timeout_callback,
|
receipt_task_finish_cleanup, receipt_recv_timeout_callback,
|
||||||
1000, sizeof(SFCommonProtoHeader), TASK_PADDING_SIZE,
|
1000, sizeof(SFCommonProtoHeader), 0, receipt_init_task, NULL);
|
||||||
task_arg_size, double_buffers, need_shrink_task_buffer,
|
|
||||||
explicit_post_recv, receipt_init_task, pd, NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int receipt_handler_init(FCAddressPtrArray *address_array)
|
int receipt_handler_init()
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result=do_init(address_array)) != 0) {
|
if ((result=do_init()) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_enable_thread_notify(true);
|
sf_enable_thread_notify(true);
|
||||||
|
sf_set_remove_from_ready_list(false);
|
||||||
fc_sleep_ms(100);
|
fc_sleep_ms(100);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int receipt_handler_init(FCAddressPtrArray *address_array);
|
int receipt_handler_init();
|
||||||
int receipt_handler_destroy();
|
int receipt_handler_destroy();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
||||||
|
|
@ -44,14 +44,14 @@
|
||||||
&client_ctx->common_cfg.net_retry_cfg.interval_mm, \
|
&client_ctx->common_cfg.net_retry_cfg.interval_mm, \
|
||||||
&client_ctx->common_cfg.net_retry_cfg.network); \
|
&client_ctx->common_cfg.net_retry_cfg.network); \
|
||||||
\
|
\
|
||||||
if (idempotency_enabled) { \
|
|
||||||
req_id = idempotency_client_channel_next_seq_id( \
|
|
||||||
connection_params->channel); \
|
|
||||||
} else { \
|
|
||||||
req_id = 0; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
while (1) { \
|
while (1) { \
|
||||||
|
if (idempotency_enabled) { \
|
||||||
|
req_id = idempotency_client_channel_next_seq_id( \
|
||||||
|
connection_params->channel); \
|
||||||
|
} else { \
|
||||||
|
req_id = 0; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
old_channel = connection_params != NULL ? \
|
old_channel = connection_params != NULL ? \
|
||||||
connection_params->channel : NULL; \
|
connection_params->channel : NULL; \
|
||||||
i = 0; \
|
i = 0; \
|
||||||
|
|
@ -79,9 +79,8 @@
|
||||||
connection_params->channel) == 0) \
|
connection_params->channel) == 0) \
|
||||||
{ \
|
{ \
|
||||||
if ((conn_result=sf_proto_rebind_idempotency_channel( \
|
if ((conn_result=sf_proto_rebind_idempotency_channel( \
|
||||||
conn, (conn_manager)->module_name, \
|
conn, connection_params->channel->id, \
|
||||||
connection_params->channel->id, \
|
connection_params->channel->key, \
|
||||||
connection_params->channel->key, \
|
|
||||||
client_ctx->common_cfg.network_timeout)) == 0) \
|
client_ctx->common_cfg.network_timeout)) == 0) \
|
||||||
{ \
|
{ \
|
||||||
continue; \
|
continue; \
|
||||||
|
|
|
||||||
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License, version 3
|
|
||||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _IDEMPOTENCY_COMMON_TYPES_H
|
|
||||||
#define _IDEMPOTENCY_COMMON_TYPES_H
|
|
||||||
|
|
||||||
#include "fastcommon/common_define.h"
|
|
||||||
|
|
||||||
#define SF_IDEMPOTENCY_CHANNEL_ID_BITS 16
|
|
||||||
#define SF_IDEMPOTENCY_REQUEST_ID_BITS (64 - SF_IDEMPOTENCY_CHANNEL_ID_BITS)
|
|
||||||
#define SF_IDEMPOTENCY_MAX_CHANNEL_COUNT ((1 << SF_IDEMPOTENCY_CHANNEL_ID_BITS) - 1)
|
|
||||||
#define SF_IDEMPOTENCY_MAX_CHANNEL_ID SF_IDEMPOTENCY_MAX_CHANNEL_COUNT
|
|
||||||
|
|
||||||
#define SF_IDEMPOTENCY_SERVER_ID_OFFSET 48
|
|
||||||
#define SF_IDEMPOTENCY_CHANNEL_ID_OFFSET 32
|
|
||||||
|
|
||||||
#define SF_IDEMPOTENCY_NEXT_REQ_ID(server_id, channel_id, seq) \
|
|
||||||
(((int64_t)server_id) << SF_IDEMPOTENCY_SERVER_ID_OFFSET) | \
|
|
||||||
(((int64_t)channel_id) << SF_IDEMPOTENCY_CHANNEL_ID_OFFSET) | \
|
|
||||||
(int64_t)seq
|
|
||||||
|
|
||||||
#define SF_IDEMPOTENCY_EXTRACT_SERVER_ID(req_id) \
|
|
||||||
(int)((req_id >> SF_IDEMPOTENCY_SERVER_ID_OFFSET) & 0xFFFF)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,250 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License, version 3
|
|
||||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <limits.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include "fastcommon/shared_func.h"
|
|
||||||
#include "fastcommon/logger.h"
|
|
||||||
#include "fastcommon/fc_atomic.h"
|
|
||||||
#include "sf/sf_global.h"
|
|
||||||
#include "request_metadata.h"
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
int process_interval_ms;
|
|
||||||
int master_side_timeout; //in seconds
|
|
||||||
struct {
|
|
||||||
IdempotencyRequestMetadataContext *head;
|
|
||||||
IdempotencyRequestMetadataContext *tail;
|
|
||||||
} list;
|
|
||||||
} g_request_metadata = {1000, 300, {NULL, NULL}};
|
|
||||||
|
|
||||||
|
|
||||||
#define CHECK_MASTER_METADATA(meta) \
|
|
||||||
(meta != NULL && g_current_time - (long)meta->enqueue_time > \
|
|
||||||
g_request_metadata.master_side_timeout)
|
|
||||||
|
|
||||||
static void process_master_side(IdempotencyRequestMetadataContext *ctx)
|
|
||||||
{
|
|
||||||
struct fast_mblock_chain chain;
|
|
||||||
struct fast_mblock_node *node;
|
|
||||||
|
|
||||||
chain.head = chain.tail = NULL;
|
|
||||||
PTHREAD_MUTEX_LOCK(&ctx->lock);
|
|
||||||
if (CHECK_MASTER_METADATA(ctx->list.head)) {
|
|
||||||
do {
|
|
||||||
node = fast_mblock_to_node_ptr(ctx->list.head);
|
|
||||||
if (chain.head == NULL) {
|
|
||||||
chain.head = node;
|
|
||||||
} else {
|
|
||||||
chain.tail->next = node;
|
|
||||||
}
|
|
||||||
chain.tail = node;
|
|
||||||
|
|
||||||
ctx->list.head = ctx->list.head->next;
|
|
||||||
} while (CHECK_MASTER_METADATA(ctx->list.head));
|
|
||||||
|
|
||||||
if (ctx->list.head == NULL) {
|
|
||||||
ctx->list.tail = NULL;
|
|
||||||
}
|
|
||||||
chain.tail->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain.head != NULL) {
|
|
||||||
fast_mblock_batch_free(&ctx->allocator, &chain);
|
|
||||||
}
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&ctx->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define CHECK_SLAVE_METADATA(meta, dv) \
|
|
||||||
(meta != NULL && meta->data_version <= dv)
|
|
||||||
|
|
||||||
static void process_slave_side(IdempotencyRequestMetadataContext *ctx,
|
|
||||||
const int64_t data_version)
|
|
||||||
{
|
|
||||||
struct fast_mblock_chain chain;
|
|
||||||
struct fast_mblock_node *node;
|
|
||||||
|
|
||||||
chain.head = chain.tail = NULL;
|
|
||||||
PTHREAD_MUTEX_LOCK(&ctx->lock);
|
|
||||||
if (CHECK_SLAVE_METADATA(ctx->list.head, data_version)) {
|
|
||||||
do {
|
|
||||||
node = fast_mblock_to_node_ptr(ctx->list.head);
|
|
||||||
if (chain.head == NULL) {
|
|
||||||
chain.head = node;
|
|
||||||
} else {
|
|
||||||
chain.tail->next = node;
|
|
||||||
}
|
|
||||||
chain.tail = node;
|
|
||||||
|
|
||||||
ctx->list.head = ctx->list.head->next;
|
|
||||||
} while (CHECK_SLAVE_METADATA(ctx->list.head, data_version));
|
|
||||||
|
|
||||||
if (ctx->list.head == NULL) {
|
|
||||||
ctx->list.tail = NULL;
|
|
||||||
}
|
|
||||||
chain.tail->next = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chain.head != NULL) {
|
|
||||||
fast_mblock_batch_free(&ctx->allocator, &chain);
|
|
||||||
}
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&ctx->lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *thread_run(void *arg)
|
|
||||||
{
|
|
||||||
IdempotencyRequestMetadataContext *ctx;
|
|
||||||
int64_t data_version;
|
|
||||||
|
|
||||||
#ifdef OS_LINUX
|
|
||||||
prctl(PR_SET_NAME, "idemp-req-meta");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
ctx = g_request_metadata.list.head;
|
|
||||||
while (SF_G_CONTINUE_FLAG) {
|
|
||||||
fc_sleep_ms(g_request_metadata.process_interval_ms);
|
|
||||||
|
|
||||||
if (ctx->is_master_callback.func(ctx->is_master_callback.
|
|
||||||
arg, &data_version))
|
|
||||||
{
|
|
||||||
process_master_side(ctx);
|
|
||||||
} else if (data_version > 0) {
|
|
||||||
process_slave_side(ctx, data_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = ctx->next;
|
|
||||||
if (ctx == NULL) {
|
|
||||||
ctx = g_request_metadata.list.head;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idempotency_request_metadata_init(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, sf_is_master_callback is_master_callback, void *arg)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if ((result=fast_mblock_init_ex1(&ctx->allocator, "req-metadata-info",
|
|
||||||
sizeof(IdempotencyRequestMetadata), 8192, 0,
|
|
||||||
NULL, NULL, false)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result=init_pthread_lock(&ctx->lock)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx->is_master_callback.func = is_master_callback;
|
|
||||||
ctx->is_master_callback.arg = arg;
|
|
||||||
ctx->list.head = ctx->list.tail = NULL;
|
|
||||||
|
|
||||||
ctx->next = NULL;
|
|
||||||
if (g_request_metadata.list.head == NULL) {
|
|
||||||
g_request_metadata.list.head = ctx;
|
|
||||||
} else {
|
|
||||||
g_request_metadata.list.tail->next = ctx;
|
|
||||||
}
|
|
||||||
g_request_metadata.list.tail = ctx;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int idempotency_request_metadata_start(const int process_interval_ms,
|
|
||||||
const int master_side_timeout)
|
|
||||||
{
|
|
||||||
pthread_t tid;
|
|
||||||
|
|
||||||
if (g_request_metadata.list.head == NULL) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"list is empty!", __LINE__);
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (process_interval_ms <= 0) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"invalid process interval: %d!",
|
|
||||||
__LINE__, process_interval_ms);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (master_side_timeout <= 0) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"invalid master side timeout: %d!",
|
|
||||||
__LINE__, master_side_timeout);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_request_metadata.process_interval_ms = process_interval_ms;
|
|
||||||
g_request_metadata.master_side_timeout = master_side_timeout;
|
|
||||||
return fc_create_thread(&tid, thread_run, NULL,
|
|
||||||
SF_G_THREAD_STACK_SIZE);
|
|
||||||
}
|
|
||||||
|
|
||||||
int idempotency_request_metadata_add(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, const SFRequestMetadata *metadata, const int n)
|
|
||||||
{
|
|
||||||
IdempotencyRequestMetadata *idemp_meta;
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&ctx->lock);
|
|
||||||
do {
|
|
||||||
if ((idemp_meta=fast_mblock_alloc_object(&ctx->allocator)) == NULL) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
idemp_meta->req_id = metadata->req_id;
|
|
||||||
idemp_meta->data_version = metadata->data_version;
|
|
||||||
idemp_meta->n = n;
|
|
||||||
idemp_meta->enqueue_time = g_current_time;
|
|
||||||
idemp_meta->next = NULL;
|
|
||||||
|
|
||||||
if (ctx->list.head == NULL) {
|
|
||||||
ctx->list.head = idemp_meta;
|
|
||||||
} else {
|
|
||||||
ctx->list.tail->next = idemp_meta;
|
|
||||||
}
|
|
||||||
ctx->list.tail = idemp_meta;
|
|
||||||
} while (0);
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&ctx->lock);
|
|
||||||
|
|
||||||
return (idemp_meta != NULL ? 0 : ENOMEM);
|
|
||||||
}
|
|
||||||
|
|
||||||
int idempotency_request_metadata_get(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, const int64_t req_id, int64_t *data_version, int *n)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
IdempotencyRequestMetadata *meta;
|
|
||||||
|
|
||||||
result = ENOENT;
|
|
||||||
PTHREAD_MUTEX_LOCK(&ctx->lock);
|
|
||||||
meta = ctx->list.head;
|
|
||||||
while (meta != NULL) {
|
|
||||||
if (req_id == meta->req_id) {
|
|
||||||
result = 0;
|
|
||||||
*data_version = meta->data_version;
|
|
||||||
if (n != NULL) {
|
|
||||||
*n = meta->n;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
meta = meta->next;
|
|
||||||
}
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&ctx->lock);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
@ -1,66 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License, version 3
|
|
||||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _SF_IDEMPOTENCY_REQUEST_METADATA_H
|
|
||||||
#define _SF_IDEMPOTENCY_REQUEST_METADATA_H
|
|
||||||
|
|
||||||
#include "server_types.h"
|
|
||||||
|
|
||||||
typedef bool (*sf_is_master_callback)(void *arg, int64_t *data_version);
|
|
||||||
|
|
||||||
typedef struct idempotency_request_metadata {
|
|
||||||
int64_t req_id;
|
|
||||||
int64_t data_version;
|
|
||||||
int n; //integer argument
|
|
||||||
uint32_t enqueue_time;
|
|
||||||
struct idempotency_request_metadata *next;
|
|
||||||
} IdempotencyRequestMetadata;
|
|
||||||
|
|
||||||
typedef struct idempotency_request_metadata_context {
|
|
||||||
struct {
|
|
||||||
sf_is_master_callback func;
|
|
||||||
void *arg;
|
|
||||||
} is_master_callback;
|
|
||||||
struct fast_mblock_man allocator; //element: IdempotencyRequestMetadata
|
|
||||||
pthread_mutex_t lock;
|
|
||||||
struct {
|
|
||||||
IdempotencyRequestMetadata *head;
|
|
||||||
IdempotencyRequestMetadata *tail;
|
|
||||||
} list;
|
|
||||||
struct idempotency_request_metadata_context *next;
|
|
||||||
} IdempotencyRequestMetadataContext;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int idempotency_request_metadata_init(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, sf_is_master_callback is_master_callback, void *arg);
|
|
||||||
|
|
||||||
int idempotency_request_metadata_start(const int process_interval_ms,
|
|
||||||
const int master_side_timeout);
|
|
||||||
|
|
||||||
int idempotency_request_metadata_add(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, const SFRequestMetadata *metadata, const int n);
|
|
||||||
|
|
||||||
int idempotency_request_metadata_get(IdempotencyRequestMetadataContext
|
|
||||||
*ctx, const int64_t req_id, int64_t *data_version, int *n);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -37,9 +37,12 @@
|
||||||
#include "server_channel.h"
|
#include "server_channel.h"
|
||||||
#include "server_handler.h"
|
#include "server_handler.h"
|
||||||
|
|
||||||
|
#define SF_TASK_BODY_LENGTH(task) \
|
||||||
|
(task->length - sizeof(SFCommonProtoHeader))
|
||||||
|
|
||||||
int sf_server_deal_setup_channel(struct fast_task_info *task,
|
int sf_server_deal_setup_channel(struct fast_task_info *task,
|
||||||
int *task_type, const int server_id, IdempotencyChannel
|
int *task_type, IdempotencyChannel **channel,
|
||||||
**channel, SFResponseInfo *response)
|
SFResponseInfo *response)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
SFProtoSetupChannelReq *req;
|
SFProtoSetupChannelReq *req;
|
||||||
|
|
@ -49,13 +52,13 @@ int sf_server_deal_setup_channel(struct fast_task_info *task,
|
||||||
|
|
||||||
response->header.cmd = SF_SERVICE_PROTO_SETUP_CHANNEL_RESP;
|
response->header.cmd = SF_SERVICE_PROTO_SETUP_CHANNEL_RESP;
|
||||||
if ((result=sf_server_expect_body_length(response,
|
if ((result=sf_server_expect_body_length(response,
|
||||||
SF_RECV_BODY_LENGTH(task),
|
SF_TASK_BODY_LENGTH(task),
|
||||||
sizeof(SFProtoSetupChannelReq))) != 0)
|
sizeof(SFProtoSetupChannelReq))) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
req = (SFProtoSetupChannelReq *)SF_PROTO_RECV_BODY(task);
|
req = (SFProtoSetupChannelReq *)(task->data + sizeof(SFCommonProtoHeader));
|
||||||
channel_id = buff2int(req->channel_id);
|
channel_id = buff2int(req->channel_id);
|
||||||
key = buff2int(req->key);
|
key = buff2int(req->key);
|
||||||
if (*channel != NULL) {
|
if (*channel != NULL) {
|
||||||
|
|
@ -71,13 +74,14 @@ int sf_server_deal_setup_channel(struct fast_task_info *task,
|
||||||
"alloc channel fail, hint channel id: %d", channel_id);
|
"alloc channel fail, hint channel id: %d", channel_id);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
*task_type = SF_SERVER_TASK_TYPE_CHANNEL_HOLDER;
|
*task_type = SF_SERVER_TASK_TYPE_CHANNEL_HOLDER;
|
||||||
|
|
||||||
resp = (SFProtoSetupChannelResp *)SF_PROTO_SEND_BODY(task);
|
resp = (SFProtoSetupChannelResp *)(task->data +
|
||||||
|
sizeof(SFCommonProtoHeader));
|
||||||
int2buff((*channel)->id, resp->channel_id);
|
int2buff((*channel)->id, resp->channel_id);
|
||||||
int2buff((*channel)->key, resp->key);
|
int2buff((*channel)->key, resp->key);
|
||||||
int2buff(server_id, resp->server_id);
|
int2buff(task->size, resp->buffer_size);
|
||||||
int2buff(task->send.ptr->size, resp->buffer_size);
|
|
||||||
response->header.body_len = sizeof(SFProtoSetupChannelResp);
|
response->header.body_len = sizeof(SFProtoSetupChannelResp);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -131,19 +135,19 @@ int sf_server_deal_report_req_receipt(struct fast_task_info *task,
|
||||||
SFProtoReportReqReceiptBody *body_part;
|
SFProtoReportReqReceiptBody *body_part;
|
||||||
SFProtoReportReqReceiptBody *body_end;
|
SFProtoReportReqReceiptBody *body_end;
|
||||||
|
|
||||||
response->header.cmd = SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_RESP;
|
|
||||||
if ((result=check_holder_channel(task_type, channel, response)) != 0) {
|
if ((result=check_holder_channel(task_type, channel, response)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
body_len = SF_RECV_BODY_LENGTH(task);
|
body_len = SF_TASK_BODY_LENGTH(task);
|
||||||
if ((result=sf_server_check_min_body_length(response, body_len,
|
if ((result=sf_server_check_min_body_length(response, body_len,
|
||||||
sizeof(SFProtoReportReqReceiptHeader))) != 0)
|
sizeof(SFProtoReportReqReceiptHeader))) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
body_header = (SFProtoReportReqReceiptHeader *)SF_PROTO_RECV_BODY(task);
|
body_header = (SFProtoReportReqReceiptHeader *)
|
||||||
|
(task->data + sizeof(SFCommonProtoHeader));
|
||||||
count = buff2int(body_header->count);
|
count = buff2int(body_header->count);
|
||||||
calc_body_len = sizeof(SFProtoReportReqReceiptHeader) +
|
calc_body_len = sizeof(SFProtoReportReqReceiptHeader) +
|
||||||
sizeof(SFProtoReportReqReceiptBody) * count;
|
sizeof(SFProtoReportReqReceiptBody) * count;
|
||||||
|
|
@ -165,6 +169,7 @@ int sf_server_deal_report_req_receipt(struct fast_task_info *task,
|
||||||
}
|
}
|
||||||
|
|
||||||
//logInfo("receipt count: %d, success: %d", count, success);
|
//logInfo("receipt count: %d, success: %d", count, success);
|
||||||
|
response->header.cmd = SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_RESP;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -184,7 +189,7 @@ IdempotencyRequest *sf_server_update_prepare_and_check(
|
||||||
}
|
}
|
||||||
|
|
||||||
adheader = (SFProtoIdempotencyAdditionalHeader *)req->body;
|
adheader = (SFProtoIdempotencyAdditionalHeader *)req->body;
|
||||||
request = fast_mblock_alloc_object(request_allocator);
|
request = (IdempotencyRequest *)fast_mblock_alloc_object(request_allocator);
|
||||||
if (request == NULL) {
|
if (request == NULL) {
|
||||||
*result = ENOMEM;
|
*result = ENOMEM;
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -215,7 +220,7 @@ int sf_server_deal_rebind_channel(struct fast_task_info *task,
|
||||||
SFProtoRebindChannelReq *req;
|
SFProtoRebindChannelReq *req;
|
||||||
|
|
||||||
if ((result=sf_server_expect_body_length(response,
|
if ((result=sf_server_expect_body_length(response,
|
||||||
SF_RECV_BODY_LENGTH(task),
|
SF_TASK_BODY_LENGTH(task),
|
||||||
sizeof(SFProtoRebindChannelReq))) != 0)
|
sizeof(SFProtoRebindChannelReq))) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -235,7 +240,7 @@ int sf_server_deal_rebind_channel(struct fast_task_info *task,
|
||||||
}
|
}
|
||||||
idempotency_channel_release(*channel, false);
|
idempotency_channel_release(*channel, false);
|
||||||
|
|
||||||
req = (SFProtoRebindChannelReq *)SF_PROTO_RECV_BODY(task);
|
req = (SFProtoRebindChannelReq *)(task->data + sizeof(SFCommonProtoHeader));
|
||||||
channel_id = buff2int(req->channel_id);
|
channel_id = buff2int(req->channel_id);
|
||||||
key = buff2int(req->key);
|
key = buff2int(req->key);
|
||||||
*channel = idempotency_channel_find_and_hold(channel_id, key, &result);
|
*channel = idempotency_channel_find_and_hold(channel_id, key, &result);
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sf_server_deal_setup_channel(struct fast_task_info *task,
|
int sf_server_deal_setup_channel(struct fast_task_info *task,
|
||||||
int *task_type, const int server_id, IdempotencyChannel
|
int *task_type, IdempotencyChannel **channel,
|
||||||
**channel, SFResponseInfo *response);
|
SFResponseInfo *response);
|
||||||
|
|
||||||
int sf_server_deal_close_channel(struct fast_task_info *task,
|
int sf_server_deal_close_channel(struct fast_task_info *task,
|
||||||
int *task_type, IdempotencyChannel **channel,
|
int *task_type, IdempotencyChannel **channel,
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,11 @@
|
||||||
|
|
||||||
#include "fastcommon/fast_mblock.h"
|
#include "fastcommon/fast_mblock.h"
|
||||||
#include "fastcommon/fast_timer.h"
|
#include "fastcommon/fast_timer.h"
|
||||||
#include "sf/idempotency/common/idempotency_types.h"
|
|
||||||
|
#define SF_IDEMPOTENCY_CHANNEL_ID_BITS 16
|
||||||
|
#define SF_IDEMPOTENCY_REQUEST_ID_BITS (64 - SF_IDEMPOTENCY_CHANNEL_ID_BITS)
|
||||||
|
#define SF_IDEMPOTENCY_MAX_CHANNEL_COUNT ((1 << SF_IDEMPOTENCY_CHANNEL_ID_BITS) - 1)
|
||||||
|
#define SF_IDEMPOTENCY_MAX_CHANNEL_ID SF_IDEMPOTENCY_MAX_CHANNEL_COUNT
|
||||||
|
|
||||||
#define SF_IDEMPOTENCY_DEFAULT_REQUEST_HINT_CAPACITY 1023
|
#define SF_IDEMPOTENCY_DEFAULT_REQUEST_HINT_CAPACITY 1023
|
||||||
#define SF_IDEMPOTENCY_DEFAULT_CHANNEL_RESERVE_INTERVAL 600
|
#define SF_IDEMPOTENCY_DEFAULT_CHANNEL_RESERVE_INTERVAL 600
|
||||||
|
|
@ -57,17 +61,6 @@ typedef struct idempotency_channel {
|
||||||
struct idempotency_channel *next;
|
struct idempotency_channel *next;
|
||||||
} IdempotencyChannel;
|
} IdempotencyChannel;
|
||||||
|
|
||||||
typedef struct sf_request_metadata {
|
|
||||||
int64_t req_id;
|
|
||||||
int64_t data_version;
|
|
||||||
} SFRequestMetadata;
|
|
||||||
|
|
||||||
typedef struct sf_request_metadata_array {
|
|
||||||
SFRequestMetadata *elts;
|
|
||||||
int count;
|
|
||||||
int alloc;
|
|
||||||
} SFRequestMetadataArray;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,10 @@ static int parse(SFBinlogIndexContext *ctx, const string_t *lines,
|
||||||
const string_t *end;
|
const string_t *end;
|
||||||
void *bindex;
|
void *bindex;
|
||||||
|
|
||||||
|
if (row_count < 1) {
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if ((result=parse_header(lines, &record_count, &ctx->
|
if ((result=parse_header(lines, &record_count, &ctx->
|
||||||
last_version, error_info)) != 0)
|
last_version, error_info)) != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -136,9 +140,7 @@ static int load(SFBinlogIndexContext *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
row_count = split_string_ex(&context, '\n', lines, row_count, true);
|
row_count = split_string_ex(&context, '\n', lines, row_count, true);
|
||||||
if (row_count > 0) {
|
result = parse(ctx, lines, row_count);
|
||||||
result = parse(ctx, lines, row_count);
|
|
||||||
}
|
|
||||||
free(lines);
|
free(lines);
|
||||||
free(context.str);
|
free(context.str);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -173,9 +175,7 @@ static int save(SFBinlogIndexContext *ctx, const char *filename)
|
||||||
int i;
|
int i;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((fd=open(filename, O_WRONLY | O_CREAT | O_TRUNC |
|
if ((fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644)) < 0) {
|
||||||
O_CLOEXEC, 0644)) < 0)
|
|
||||||
{
|
|
||||||
result = errno != 0 ? errno : EIO;
|
result = errno != 0 ? errno : EIO;
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"open file %s fail, errno: %d, error info: %s",
|
"open file %s fail, errno: %d, error info: %s",
|
||||||
|
|
@ -186,11 +186,9 @@ static int save(SFBinlogIndexContext *ctx, const char *filename)
|
||||||
result = 0;
|
result = 0;
|
||||||
p = buff;
|
p = buff;
|
||||||
bend = buff + sizeof(buff);
|
bend = buff + sizeof(buff);
|
||||||
|
p += sprintf(p, "%d %"PRId64"\n",
|
||||||
p += fc_itoa(ctx->index_array.count, p);
|
ctx->index_array.count,
|
||||||
*p++ = ' ';
|
ctx->last_version);
|
||||||
p += fc_itoa(ctx->last_version, p);
|
|
||||||
*p++ = '\n';
|
|
||||||
|
|
||||||
index = ctx->index_array.indexes;
|
index = ctx->index_array.indexes;
|
||||||
for (i=0; i<ctx->index_array.count; i++) {
|
for (i=0; i<ctx->index_array.count; i++) {
|
||||||
|
|
@ -229,7 +227,7 @@ int sf_binlog_index_save(SFBinlogIndexContext *ctx)
|
||||||
int result;
|
int result;
|
||||||
char tmp_filename[PATH_MAX];
|
char tmp_filename[PATH_MAX];
|
||||||
|
|
||||||
fc_combine_two_strings(ctx->filename, "tmp", '.', tmp_filename);
|
snprintf(tmp_filename, sizeof(tmp_filename), "%s.tmp", ctx->filename);
|
||||||
if ((result=save(ctx, tmp_filename)) != 0) {
|
if ((result=save(ctx, tmp_filename)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,18 @@
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <netinet/in.h>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <pthread.h>
|
||||||
#include "fastcommon/logger.h"
|
#include "fastcommon/logger.h"
|
||||||
#include "fastcommon/sockopt.h"
|
#include "fastcommon/sockopt.h"
|
||||||
#include "fastcommon/shared_func.h"
|
#include "fastcommon/shared_func.h"
|
||||||
|
|
@ -22,8 +34,6 @@
|
||||||
#include "sf_func.h"
|
#include "sf_func.h"
|
||||||
#include "sf_binlog_writer.h"
|
#include "sf_binlog_writer.h"
|
||||||
|
|
||||||
#define ERRNO_THREAD_EXIT -1000
|
|
||||||
|
|
||||||
static inline void binlog_writer_set_next_version(SFBinlogWriterInfo *writer,
|
static inline void binlog_writer_set_next_version(SFBinlogWriterInfo *writer,
|
||||||
const uint64_t next_version)
|
const uint64_t next_version)
|
||||||
{
|
{
|
||||||
|
|
@ -34,8 +44,7 @@ static inline void binlog_writer_set_next_version(SFBinlogWriterInfo *writer,
|
||||||
}
|
}
|
||||||
|
|
||||||
#define deal_binlog_one_record(wb) \
|
#define deal_binlog_one_record(wb) \
|
||||||
sf_file_writer_deal_versioned_buffer(&wb->writer->fw, \
|
sf_file_writer_deal_buffer(&wb->writer->fw, &wb->bf, wb->version.last)
|
||||||
&wb->bf, wb->version.last)
|
|
||||||
|
|
||||||
#define GET_WBUFFER_VERSION_COUNT(wb) \
|
#define GET_WBUFFER_VERSION_COUNT(wb) \
|
||||||
(((wb)->version.last - (wb)->version.first) + 1)
|
(((wb)->version.last - (wb)->version.first) + 1)
|
||||||
|
|
@ -61,9 +70,9 @@ static int deal_record_by_version(SFBinlogWriterBuffer *wb)
|
||||||
if (wb->version.first < writer->version_ctx.next) {
|
if (wb->version.first < writer->version_ctx.next) {
|
||||||
logError("file: "__FILE__", line: %d, subdir_name: %s, "
|
logError("file: "__FILE__", line: %d, subdir_name: %s, "
|
||||||
"current version: %"PRId64" is too small which "
|
"current version: %"PRId64" is too small which "
|
||||||
"less than %"PRId64", buffer(%d): %.*s",
|
"less than %"PRId64", tag: %"PRId64", buffer(%d): %.*s",
|
||||||
__LINE__, writer->fw.cfg.subdir_name, wb->version.first,
|
__LINE__, writer->fw.cfg.subdir_name, wb->version.first,
|
||||||
writer->version_ctx.next, wb->bf.length,
|
writer->version_ctx.next, wb->tag, wb->bf.length,
|
||||||
wb->bf.length, wb->bf.buff);
|
wb->bf.length, wb->bf.buff);
|
||||||
fast_mblock_free_object(&writer->thread->mblock, wb);
|
fast_mblock_free_object(&writer->thread->mblock, wb);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -156,6 +165,9 @@ static inline int flush_writer_files(SFBinlogWriterThread *thread)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (writer->fw.flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
||||||
|
writer->fw.last_versions.done = writer->fw.last_versions.pending;
|
||||||
|
}
|
||||||
writer->flush.in_queue = false;
|
writer->flush.in_queue = false;
|
||||||
writer = writer->flush.next;
|
writer = writer->flush.next;
|
||||||
}
|
}
|
||||||
|
|
@ -165,10 +177,9 @@ static inline int flush_writer_files(SFBinlogWriterThread *thread)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int deal_binlog_records(SFBinlogWriterThread *thread,
|
static int deal_binlog_records(SFBinlogWriterThread *thread,
|
||||||
SFBinlogWriterBuffer *wb_head, uint32_t *last_timestamp)
|
SFBinlogWriterBuffer *wb_head)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
bool skip_empty_file;
|
|
||||||
SFBinlogWriterBuffer *wbuffer;
|
SFBinlogWriterBuffer *wbuffer;
|
||||||
SFBinlogWriterBuffer *current;
|
SFBinlogWriterBuffer *current;
|
||||||
|
|
||||||
|
|
@ -176,73 +187,21 @@ static int deal_binlog_records(SFBinlogWriterThread *thread,
|
||||||
do {
|
do {
|
||||||
current = wbuffer;
|
current = wbuffer;
|
||||||
wbuffer = wbuffer->next;
|
wbuffer = wbuffer->next;
|
||||||
if (wbuffer == NULL) {
|
|
||||||
*last_timestamp = current->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (current->type) {
|
switch (current->type) {
|
||||||
case SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE:
|
case SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE:
|
||||||
current->writer->order_by = current->version.first;
|
thread->order_by = current->version.first;
|
||||||
fast_mblock_free_object(¤t->writer->
|
fast_mblock_free_object(¤t->writer->
|
||||||
thread->mblock, current);
|
thread->mblock, current);
|
||||||
break;
|
break;
|
||||||
case SF_BINLOG_BUFFER_TYPE_CHANGE_PASSIVE_WRITE:
|
|
||||||
thread->passive_write = current->version.first;
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
break;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_CHANGE_CALL_FSYNC:
|
|
||||||
current->writer->fw.cfg.call_fsync = current->version.first;
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
break;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_ROTATE_FILE:
|
|
||||||
flush_writer_files(thread);
|
|
||||||
skip_empty_file = current->version.first;
|
|
||||||
if (!(skip_empty_file && current->writer->fw.file.size == 0)) {
|
|
||||||
if ((result=sf_file_writer_set_binlog_write_index(¤t->
|
|
||||||
writer->fw, current->writer->fw.binlog.
|
|
||||||
last_index + 1)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
break;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_FLUSH_FILE:
|
|
||||||
if ((result=flush_writer_files(thread)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
break;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_SET_WRITE_INDEX:
|
|
||||||
if ((result=sf_file_writer_set_binlog_write_index(¤t->
|
|
||||||
writer->fw, current->version.first)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
break;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_NOTIFY_EXIT:
|
|
||||||
flush_writer_files(thread);
|
|
||||||
fast_mblock_free_object(¤t->writer->
|
|
||||||
thread->mblock, current);
|
|
||||||
return ERRNO_THREAD_EXIT;
|
|
||||||
case SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION:
|
case SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION:
|
||||||
if (current->writer->order_by !=
|
if (thread->order_by != SF_BINLOG_THREAD_TYPE_ORDER_BY_VERSION) {
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION &&
|
|
||||||
current->writer->thread->order_mode !=
|
|
||||||
SF_BINLOG_THREAD_ORDER_MODE_VARY)
|
|
||||||
{
|
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"subdir_name: %s, order by: %d != %d, "
|
"subdir_name: %s, invalid order by: %d != %d, "
|
||||||
"maybe some mistake happen?", __LINE__,
|
"maybe some mistake happen", __LINE__,
|
||||||
current->writer->fw.cfg.subdir_name,
|
current->writer->fw.cfg.subdir_name, thread->order_by,
|
||||||
current->writer->order_by,
|
SF_BINLOG_THREAD_TYPE_ORDER_BY_VERSION);
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current->writer->version_ctx.ring.waiting_count != 0) {
|
if (current->writer->version_ctx.ring.waiting_count != 0) {
|
||||||
|
|
@ -257,10 +216,8 @@ static int deal_binlog_records(SFBinlogWriterThread *thread,
|
||||||
__LINE__, current->writer->fw.cfg.subdir_name,
|
__LINE__, current->writer->fw.cfg.subdir_name,
|
||||||
current->version.first);
|
current->version.first);
|
||||||
|
|
||||||
if ((current->writer->order_by ==
|
if (current->writer->version_ctx.next !=
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_NONE) ||
|
current->version.first)
|
||||||
(current->writer->version_ctx.next !=
|
|
||||||
current->version.first))
|
|
||||||
{
|
{
|
||||||
binlog_writer_set_next_version(current->writer,
|
binlog_writer_set_next_version(current->writer,
|
||||||
current->version.first);
|
current->version.first);
|
||||||
|
|
@ -269,13 +226,12 @@ static int deal_binlog_records(SFBinlogWriterThread *thread,
|
||||||
fast_mblock_free_object(¤t->writer->
|
fast_mblock_free_object(¤t->writer->
|
||||||
thread->mblock, current);
|
thread->mblock, current);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
current->writer->fw.total_count++;
|
current->writer->fw.total_count++;
|
||||||
add_to_flush_writer_queue(thread, current->writer);
|
add_to_flush_writer_queue(thread, current->writer);
|
||||||
|
|
||||||
if (current->writer->order_by ==
|
if (thread->order_by == SF_BINLOG_THREAD_TYPE_ORDER_BY_VERSION) {
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION)
|
|
||||||
{
|
|
||||||
/* NOTE: current maybe be released in the deal function */
|
/* NOTE: current maybe be released in the deal function */
|
||||||
if ((result=deal_record_by_version(current)) != 0) {
|
if ((result=deal_record_by_version(current)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -292,31 +248,19 @@ static int deal_binlog_records(SFBinlogWriterThread *thread,
|
||||||
}
|
}
|
||||||
} while (wbuffer != NULL);
|
} while (wbuffer != NULL);
|
||||||
|
|
||||||
if (thread->passive_write) {
|
return flush_writer_files(thread);
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return flush_writer_files(thread);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_binlog_writer_finish(SFBinlogWriterInfo *writer)
|
void sf_binlog_writer_finish(SFBinlogWriterInfo *writer)
|
||||||
{
|
{
|
||||||
SFBinlogWriterBuffer *wb_head;
|
SFBinlogWriterBuffer *wb_head;
|
||||||
uint32_t last_timestamp;
|
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (writer->fw.file.name.str != NULL) {
|
if (writer->fw.file.name != NULL) {
|
||||||
while (writer->thread->running && !fc_queue_empty(
|
fc_queue_terminate(&writer->thread->queue);
|
||||||
&writer->thread->queue))
|
|
||||||
{
|
|
||||||
fc_sleep_ms(10);
|
|
||||||
}
|
|
||||||
if (writer->thread->running) {
|
|
||||||
sf_binlog_writer_notify_exit(writer);
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
while (writer->thread->running && ++count < 500) {
|
while (writer->thread->running && ++count < 300) {
|
||||||
fc_sleep_ms(10);
|
fc_sleep_ms(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -329,12 +273,11 @@ void sf_binlog_writer_finish(SFBinlogWriterInfo *writer)
|
||||||
wb_head = (SFBinlogWriterBuffer *)fc_queue_try_pop_all(
|
wb_head = (SFBinlogWriterBuffer *)fc_queue_try_pop_all(
|
||||||
&writer->thread->queue);
|
&writer->thread->queue);
|
||||||
if (wb_head != NULL) {
|
if (wb_head != NULL) {
|
||||||
last_timestamp = 0;
|
deal_binlog_records(writer->thread, wb_head);
|
||||||
deal_binlog_records(writer->thread, wb_head, &last_timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
free(writer->fw.file.name.str);
|
free(writer->fw.file.name);
|
||||||
writer->fw.file.name.str = NULL;
|
writer->fw.file.name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writer->fw.file.fd >= 0) {
|
if (writer->fw.file.fd >= 0) {
|
||||||
|
|
@ -347,22 +290,18 @@ static void *binlog_writer_func(void *arg)
|
||||||
{
|
{
|
||||||
SFBinlogWriterThread *thread;
|
SFBinlogWriterThread *thread;
|
||||||
SFBinlogWriterBuffer *wb_head;
|
SFBinlogWriterBuffer *wb_head;
|
||||||
uint32_t last_record_time;
|
|
||||||
uint32_t current_timestamp;
|
|
||||||
uint32_t last_timestamp;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
thread = (SFBinlogWriterThread *)arg;
|
thread = (SFBinlogWriterThread *)arg;
|
||||||
|
|
||||||
#ifdef OS_LINUX
|
#ifdef OS_LINUX
|
||||||
{
|
{
|
||||||
char thread_name[64];
|
char thread_name[64];
|
||||||
fc_combine_two_strings(thread->name, "writer", '-', thread_name);
|
snprintf(thread_name, sizeof(thread_name),
|
||||||
|
"%s-writer", thread->name);
|
||||||
prctl(PR_SET_NAME, thread_name);
|
prctl(PR_SET_NAME, thread_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
last_record_time = current_timestamp = last_timestamp = 0;
|
|
||||||
thread->running = true;
|
thread->running = true;
|
||||||
while (SF_G_CONTINUE_FLAG) {
|
while (SF_G_CONTINUE_FLAG) {
|
||||||
wb_head = (SFBinlogWriterBuffer *)fc_queue_pop_all(&thread->queue);
|
wb_head = (SFBinlogWriterBuffer *)fc_queue_pop_all(&thread->queue);
|
||||||
|
|
@ -370,41 +309,11 @@ static void *binlog_writer_func(void *arg)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=deal_binlog_records(thread, wb_head,
|
if (deal_binlog_records(thread, wb_head) != 0) {
|
||||||
&last_record_time)) != 0)
|
logCrit("file: "__FILE__", line: %d, "
|
||||||
{
|
"deal_binlog_records fail, "
|
||||||
if (result != ERRNO_THREAD_EXIT) {
|
"program exit!", __LINE__);
|
||||||
logCrit("file: "__FILE__", line: %d, "
|
sf_terminate_myself();
|
||||||
"deal_binlog_records fail, "
|
|
||||||
"program exit!", __LINE__);
|
|
||||||
sf_terminate_myself();
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fc_queue_empty(&thread->queue)) {
|
|
||||||
current_timestamp = 0;
|
|
||||||
} else {
|
|
||||||
current_timestamp = last_record_time;
|
|
||||||
}
|
|
||||||
if ((current_timestamp == 0 && last_timestamp != 0) ||
|
|
||||||
(current_timestamp > last_timestamp))
|
|
||||||
{
|
|
||||||
last_timestamp = current_timestamp;
|
|
||||||
FC_ATOMIC_SET(thread->flow_ctrol.last_timestamp,
|
|
||||||
current_timestamp);
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&thread->flow_ctrol.lcp.lock);
|
|
||||||
if (thread->flow_ctrol.waiting_count > 0) {
|
|
||||||
pthread_cond_broadcast(&thread->flow_ctrol.lcp.cond);
|
|
||||||
}
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&thread->flow_ctrol.lcp.lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (thread->write_interval_ms > 0 &&
|
|
||||||
last_record_time == g_current_time)
|
|
||||||
{
|
|
||||||
fc_sleep_ms(thread->write_interval_ms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -432,34 +341,19 @@ static int binlog_wbuffer_alloc_init(void *element, void *args)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void binlog_wbuffer_destroy_func(void *element, void *args)
|
int sf_binlog_writer_init_normal(SFBinlogWriterInfo *writer,
|
||||||
|
const char *data_path, const char *subdir_name,
|
||||||
|
const int buffer_size)
|
||||||
{
|
{
|
||||||
SFBinlogWriterBuffer *wbuffer;
|
writer->flush.in_queue = false;
|
||||||
wbuffer = (SFBinlogWriterBuffer *)element;
|
return sf_file_writer_init_normal(&writer->fw,
|
||||||
if (wbuffer->bf.buff != NULL) {
|
data_path, subdir_name, buffer_size);
|
||||||
free(wbuffer->bf.buff);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_binlog_writer_init_normal_ex(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_init_by_version(SFBinlogWriterInfo *writer,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int max_record_size,
|
|
||||||
const int buffer_size, const int64_t file_rotate_size,
|
|
||||||
const bool call_fsync)
|
|
||||||
{
|
|
||||||
memset(writer, 0, sizeof(*writer));
|
|
||||||
writer->order_by = SF_BINLOG_WRITER_TYPE_ORDER_BY_NONE;
|
|
||||||
return sf_file_writer_init(&writer->fw, data_path, subdir_name,
|
|
||||||
file_prefix, max_record_size, buffer_size,
|
|
||||||
file_rotate_size, call_fsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_init_by_version_ex(SFBinlogWriterInfo *writer,
|
|
||||||
const char *data_path, const char *subdir_name,
|
|
||||||
const char *file_prefix, const int max_record_size,
|
|
||||||
const uint64_t next_version, const int buffer_size,
|
const uint64_t next_version, const int buffer_size,
|
||||||
const int ring_size, const int64_t file_rotate_size,
|
const int ring_size)
|
||||||
const bool call_fsync)
|
|
||||||
{
|
{
|
||||||
int bytes;
|
int bytes;
|
||||||
|
|
||||||
|
|
@ -473,49 +367,36 @@ int sf_binlog_writer_init_by_version_ex(SFBinlogWriterInfo *writer,
|
||||||
writer->version_ctx.ring.waiting_count = 0;
|
writer->version_ctx.ring.waiting_count = 0;
|
||||||
writer->version_ctx.ring.max_waitings = 0;
|
writer->version_ctx.ring.max_waitings = 0;
|
||||||
writer->version_ctx.change_count = 0;
|
writer->version_ctx.change_count = 0;
|
||||||
writer->order_by = SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION;
|
|
||||||
|
|
||||||
binlog_writer_set_next_version(writer, next_version);
|
binlog_writer_set_next_version(writer, next_version);
|
||||||
writer->flush.in_queue = false;
|
return sf_binlog_writer_init_normal(writer,
|
||||||
return sf_file_writer_init(&writer->fw, data_path, subdir_name,
|
data_path, subdir_name, buffer_size);
|
||||||
file_prefix, max_record_size, buffer_size,
|
|
||||||
file_rotate_size, call_fsync);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_binlog_writer_init_thread_ex(SFBinlogWriterThread *thread,
|
int sf_binlog_writer_init_thread_ex(SFBinlogWriterThread *thread,
|
||||||
const char *name, SFBinlogWriterInfo *writer, const short order_mode,
|
const char *name, SFBinlogWriterInfo *writer, const short order_mode,
|
||||||
const int write_interval_ms, const int max_delay,
|
const short order_by, const int max_record_size,
|
||||||
const int max_record_size, const bool use_fixed_buffer_size,
|
const int writer_count, const bool use_fixed_buffer_size)
|
||||||
const bool passive_write)
|
|
||||||
{
|
{
|
||||||
const int alloc_elements_once = 1024;
|
const int alloc_elements_once = 1024;
|
||||||
const int64_t alloc_elements_limit = 0;
|
|
||||||
const int prealloc_trunk_count = 0;
|
|
||||||
int result;
|
|
||||||
int element_size;
|
int element_size;
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
struct fast_mblock_object_callbacks callbacks;
|
int result;
|
||||||
|
|
||||||
fc_safe_strcpy(thread->name, name);
|
snprintf(thread->name, sizeof(thread->name), "%s", name);
|
||||||
thread->order_mode = order_mode;
|
thread->order_mode = order_mode;
|
||||||
|
thread->order_by = order_by;
|
||||||
thread->use_fixed_buffer_size = use_fixed_buffer_size;
|
thread->use_fixed_buffer_size = use_fixed_buffer_size;
|
||||||
thread->passive_write = passive_write;
|
|
||||||
thread->write_interval_ms = write_interval_ms;
|
|
||||||
thread->flow_ctrol.max_delay = max_delay;
|
|
||||||
writer->fw.cfg.max_record_size = max_record_size;
|
writer->fw.cfg.max_record_size = max_record_size;
|
||||||
writer->thread = thread;
|
writer->thread = thread;
|
||||||
callbacks.init_func = binlog_wbuffer_alloc_init;
|
|
||||||
callbacks.args = writer;
|
|
||||||
element_size = sizeof(SFBinlogWriterBuffer);
|
element_size = sizeof(SFBinlogWriterBuffer);
|
||||||
if (use_fixed_buffer_size) {
|
if (use_fixed_buffer_size) {
|
||||||
element_size += max_record_size;
|
element_size += max_record_size;
|
||||||
callbacks.destroy_func = NULL;
|
|
||||||
} else {
|
|
||||||
callbacks.destroy_func = binlog_wbuffer_destroy_func;
|
|
||||||
}
|
}
|
||||||
if ((result=fast_mblock_init_ex2(&thread->mblock, "binlog-wbuffer",
|
if ((result=fast_mblock_init_ex1(&thread->mblock, "binlog-wbuffer",
|
||||||
element_size, alloc_elements_once, alloc_elements_limit,
|
element_size, alloc_elements_once, 0,
|
||||||
prealloc_trunk_count, &callbacks, true, NULL)) != 0)
|
binlog_wbuffer_alloc_init, writer, true)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -526,12 +407,6 @@ int sf_binlog_writer_init_thread_ex(SFBinlogWriterThread *thread,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
thread->flow_ctrol.last_timestamp = 0;
|
|
||||||
thread->flow_ctrol.waiting_count = 0;
|
|
||||||
if ((result=init_pthread_lock_cond_pair(&thread->flow_ctrol.lcp)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread->flush_writers.head = thread->flush_writers.tail = NULL;
|
thread->flush_writers.head = thread->flush_writers.tail = NULL;
|
||||||
return fc_create_thread(&tid, binlog_writer_func, thread,
|
return fc_create_thread(&tid, binlog_writer_func, thread,
|
||||||
SF_G_THREAD_STACK_SIZE);
|
SF_G_THREAD_STACK_SIZE);
|
||||||
|
|
@ -542,12 +417,12 @@ int sf_binlog_writer_change_order_by(SFBinlogWriterInfo *writer,
|
||||||
{
|
{
|
||||||
SFBinlogWriterBuffer *buffer;
|
SFBinlogWriterBuffer *buffer;
|
||||||
|
|
||||||
if (writer->order_by == order_by) {
|
if (writer->thread->order_by == order_by) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(order_by == SF_BINLOG_WRITER_TYPE_ORDER_BY_NONE ||
|
if (!(order_by == SF_BINLOG_THREAD_TYPE_ORDER_BY_NONE ||
|
||||||
order_by == SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION))
|
order_by == SF_BINLOG_THREAD_TYPE_ORDER_BY_VERSION))
|
||||||
{
|
{
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"invalid order by: %d!", __LINE__, order_by);
|
"invalid order by: %d!", __LINE__, order_by);
|
||||||
|
|
@ -562,147 +437,27 @@ int sf_binlog_writer_change_order_by(SFBinlogWriterInfo *writer,
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (order_by == SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION) {
|
|
||||||
if (writer->version_ctx.ring.slots == NULL) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"the writer is NOT versioned writer, can't "
|
|
||||||
"set order by to %d!", __LINE__, order_by);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((buffer=sf_binlog_writer_alloc_versioned_buffer_ex(writer, order_by,
|
if ((buffer=sf_binlog_writer_alloc_versioned_buffer_ex(writer, order_by,
|
||||||
order_by, SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE)) == NULL)
|
order_by, SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE)) == NULL)
|
||||||
{
|
{
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_push_to_binlog_write_queue(writer, buffer);
|
fc_queue_push(&writer->thread->queue, buffer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sf_binlog_writer_push_directive(SFBinlogWriterInfo *writer,
|
|
||||||
const int buffer_type, const int64_t version)
|
|
||||||
{
|
|
||||||
SFBinlogWriterBuffer *buffer;
|
|
||||||
|
|
||||||
if ((buffer=sf_binlog_writer_alloc_versioned_buffer_ex(writer,
|
|
||||||
version, version, buffer_type)) == NULL)
|
|
||||||
{
|
|
||||||
return ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
sf_push_to_binlog_write_queue(writer, buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_passive_write(SFBinlogWriterInfo *writer,
|
|
||||||
const bool passive_write)
|
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_CHANGE_PASSIVE_WRITE,
|
|
||||||
passive_write);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_call_fsync(SFBinlogWriterInfo *writer,
|
|
||||||
const bool call_fsync)
|
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_CHANGE_CALL_FSYNC,
|
|
||||||
call_fsync);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_next_version(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_change_next_version(SFBinlogWriterInfo *writer,
|
||||||
const int64_t next_version)
|
const int64_t next_version)
|
||||||
{
|
{
|
||||||
return sf_binlog_writer_push_directive(writer,
|
SFBinlogWriterBuffer *buffer;
|
||||||
SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION,
|
|
||||||
next_version);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_write_index(SFBinlogWriterInfo *writer,
|
if ((buffer=sf_binlog_writer_alloc_versioned_buffer_ex(writer, next_version,
|
||||||
const int write_index)
|
next_version, SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION)) == NULL)
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_SET_WRITE_INDEX, write_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_rotate_file_ex(SFBinlogWriterInfo *writer,
|
|
||||||
const bool skip_empty_file)
|
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_ROTATE_FILE,
|
|
||||||
skip_empty_file ? 1 : 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_flush_file(SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_FLUSH_FILE, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_notify_exit(SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
return sf_binlog_writer_push_directive(writer,
|
|
||||||
SF_BINLOG_BUFFER_TYPE_NOTIFY_EXIT, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_push_to_binlog_write_queue(SFBinlogWriterInfo *writer,
|
|
||||||
SFBinlogWriterBuffer *buffer)
|
|
||||||
{
|
|
||||||
time_t current_time;
|
|
||||||
int64_t last_timestamp;
|
|
||||||
|
|
||||||
current_time = g_current_time;
|
|
||||||
last_timestamp = FC_ATOMIC_GET(writer->thread->flow_ctrol.last_timestamp);
|
|
||||||
if ((last_timestamp > 0 && current_time - last_timestamp > writer->
|
|
||||||
thread->flow_ctrol.max_delay) && !(writer->order_by ==
|
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION && buffer->
|
|
||||||
version.first - writer->version_ctx.next < 128))
|
|
||||||
{
|
{
|
||||||
time_t last_log_timestamp;
|
return ENOMEM;
|
||||||
int time_used;
|
|
||||||
int log_level;
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&writer->thread->flow_ctrol.lcp.lock);
|
|
||||||
writer->thread->flow_ctrol.waiting_count++;
|
|
||||||
last_timestamp = FC_ATOMIC_GET(writer->thread->
|
|
||||||
flow_ctrol.last_timestamp);
|
|
||||||
while ((last_timestamp > 0 && current_time - last_timestamp > writer->
|
|
||||||
thread->flow_ctrol.max_delay) && !(writer->order_by ==
|
|
||||||
SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION && buffer->
|
|
||||||
version.first - writer->version_ctx.next < 128))
|
|
||||||
{
|
|
||||||
pthread_cond_wait(&writer->thread->flow_ctrol.lcp.cond,
|
|
||||||
&writer->thread->flow_ctrol.lcp.lock);
|
|
||||||
last_timestamp = FC_ATOMIC_GET(writer->thread->
|
|
||||||
flow_ctrol.last_timestamp);
|
|
||||||
}
|
|
||||||
writer->thread->flow_ctrol.waiting_count--;
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&writer->thread->flow_ctrol.lcp.lock);
|
|
||||||
|
|
||||||
time_used = g_current_time - current_time;
|
|
||||||
if (time_used > 0) {
|
|
||||||
last_log_timestamp = FC_ATOMIC_GET(
|
|
||||||
LAST_BINLOG_WRITER_LOG_TIMESTAMP);
|
|
||||||
if (g_current_time != last_log_timestamp &&
|
|
||||||
__sync_bool_compare_and_swap(
|
|
||||||
&LAST_BINLOG_WRITER_LOG_TIMESTAMP,
|
|
||||||
last_log_timestamp, g_current_time))
|
|
||||||
{
|
|
||||||
if (time_used <= writer->thread->flow_ctrol.max_delay) {
|
|
||||||
log_level = LOG_DEBUG;
|
|
||||||
} else {
|
|
||||||
log_level = LOG_WARNING;
|
|
||||||
}
|
|
||||||
log_it_ex(&g_log_context, log_level, "file: "__FILE__", line: %d, "
|
|
||||||
"subdir_name: %s, max_delay: %d s, flow ctrol waiting "
|
|
||||||
"time: %d s", __LINE__, writer->fw.cfg.subdir_name,
|
|
||||||
writer->thread->flow_ctrol.max_delay, time_used);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->timestamp = g_current_time;
|
|
||||||
fc_queue_push(&writer->thread->queue, buffer);
|
fc_queue_push(&writer->thread->queue, buffer);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,25 +19,18 @@
|
||||||
#define _SF_BINLOG_WRITER_H_
|
#define _SF_BINLOG_WRITER_H_
|
||||||
|
|
||||||
#include "fastcommon/fc_queue.h"
|
#include "fastcommon/fc_queue.h"
|
||||||
#include "fastcommon/fc_atomic.h"
|
|
||||||
#include "sf_types.h"
|
#include "sf_types.h"
|
||||||
#include "sf_file_writer.h"
|
#include "sf_file_writer.h"
|
||||||
|
|
||||||
#define SF_BINLOG_THREAD_ORDER_MODE_FIXED 0
|
#define SF_BINLOG_THREAD_ORDER_MODE_FIXED 0
|
||||||
#define SF_BINLOG_THREAD_ORDER_MODE_VARY 1
|
#define SF_BINLOG_THREAD_ORDER_MODE_VARY 1
|
||||||
|
|
||||||
#define SF_BINLOG_WRITER_TYPE_ORDER_BY_NONE 0
|
#define SF_BINLOG_THREAD_TYPE_ORDER_BY_NONE 0
|
||||||
#define SF_BINLOG_WRITER_TYPE_ORDER_BY_VERSION 1
|
#define SF_BINLOG_THREAD_TYPE_ORDER_BY_VERSION 1
|
||||||
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_WRITE_TO_FILE 0 //default type, must be 0
|
#define SF_BINLOG_BUFFER_TYPE_WRITE_TO_FILE 0 //default type, must be 0
|
||||||
#define SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION 1
|
#define SF_BINLOG_BUFFER_TYPE_SET_NEXT_VERSION 1
|
||||||
#define SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE 2
|
#define SF_BINLOG_BUFFER_TYPE_CHANGE_ORDER_TYPE 2
|
||||||
#define SF_BINLOG_BUFFER_TYPE_CHANGE_PASSIVE_WRITE 3
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_CHANGE_CALL_FSYNC 4
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_SET_WRITE_INDEX 5
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_ROTATE_FILE 6
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_NOTIFY_EXIT 7
|
|
||||||
#define SF_BINLOG_BUFFER_TYPE_FLUSH_FILE 8
|
|
||||||
|
|
||||||
#define SF_BINLOG_BUFFER_SET_VERSION(buffer, ver) \
|
#define SF_BINLOG_BUFFER_SET_VERSION(buffer, ver) \
|
||||||
(buffer)->version.first = (buffer)->version.last = ver
|
(buffer)->version.first = (buffer)->version.last = ver
|
||||||
|
|
@ -47,8 +40,8 @@ struct sf_binlog_writer_info;
|
||||||
typedef struct sf_binlog_writer_buffer {
|
typedef struct sf_binlog_writer_buffer {
|
||||||
SFVersionRange version;
|
SFVersionRange version;
|
||||||
BufferInfo bf;
|
BufferInfo bf;
|
||||||
int type;
|
int64_t tag;
|
||||||
uint32_t timestamp; //for flow ctrol
|
int type; //for versioned writer
|
||||||
struct sf_binlog_writer_info *writer;
|
struct sf_binlog_writer_info *writer;
|
||||||
struct sf_binlog_writer_buffer *next;
|
struct sf_binlog_writer_buffer *next;
|
||||||
} SFBinlogWriterBuffer;
|
} SFBinlogWriterBuffer;
|
||||||
|
|
@ -70,15 +63,8 @@ typedef struct binlog_writer_thread {
|
||||||
char name[64];
|
char name[64];
|
||||||
volatile bool running;
|
volatile bool running;
|
||||||
bool use_fixed_buffer_size;
|
bool use_fixed_buffer_size;
|
||||||
bool passive_write;
|
short order_mode;
|
||||||
char order_mode;
|
short order_by;
|
||||||
int write_interval_ms;
|
|
||||||
struct {
|
|
||||||
int max_delay; //in seconds
|
|
||||||
volatile uint32_t last_timestamp;
|
|
||||||
int waiting_count;
|
|
||||||
pthread_lock_cond_pair_t lcp;
|
|
||||||
} flow_ctrol;
|
|
||||||
struct {
|
struct {
|
||||||
struct sf_binlog_writer_info *head;
|
struct sf_binlog_writer_info *head;
|
||||||
struct sf_binlog_writer_info *tail;
|
struct sf_binlog_writer_info *tail;
|
||||||
|
|
@ -90,12 +76,11 @@ typedef struct sf_binlog_writer_info {
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
SFBinlogWriterBufferRing ring;
|
SFBinlogWriterBufferRing ring;
|
||||||
volatile int64_t next;
|
int64_t next;
|
||||||
int64_t change_count; //version change count
|
int64_t change_count; //version change count
|
||||||
} version_ctx;
|
} version_ctx;
|
||||||
SFBinlogWriterThread *thread;
|
SFBinlogWriterThread *thread;
|
||||||
|
|
||||||
short order_by;
|
|
||||||
struct {
|
struct {
|
||||||
bool in_queue;
|
bool in_queue;
|
||||||
struct sf_binlog_writer_info *next;
|
struct sf_binlog_writer_info *next;
|
||||||
|
|
@ -111,172 +96,58 @@ typedef struct sf_binlog_writer_context {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sf_binlog_writer_init_normal_ex(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_init_normal(SFBinlogWriterInfo *writer,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int max_record_size,
|
const int buffer_size);
|
||||||
const int buffer_size, const int64_t file_rotate_size,
|
|
||||||
const bool call_fsync);
|
|
||||||
|
|
||||||
int sf_binlog_writer_init_by_version_ex(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_init_by_version(SFBinlogWriterInfo *writer,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int max_record_size,
|
|
||||||
const uint64_t next_version, const int buffer_size,
|
const uint64_t next_version, const int buffer_size,
|
||||||
const int ring_size, const int64_t file_rotate_size,
|
const int ring_size);
|
||||||
const bool call_fsync);
|
|
||||||
|
|
||||||
int sf_binlog_writer_init_thread_ex(SFBinlogWriterThread *thread,
|
int sf_binlog_writer_init_thread_ex(SFBinlogWriterThread *thread,
|
||||||
const char *name, SFBinlogWriterInfo *writer, const short order_mode,
|
const char *name, SFBinlogWriterInfo *writer, const short order_mode,
|
||||||
const int write_interval_ms, const int max_delay,
|
const short order_by, const int max_record_size,
|
||||||
const int max_record_size, const bool use_fixed_buffer_size,
|
const int writer_count, const bool use_fixed_buffer_size);
|
||||||
const bool passive_write);
|
|
||||||
|
|
||||||
#define sf_binlog_writer_init_normal(writer, data_path, \
|
|
||||||
subdir_name, max_record_size, buffer_size) \
|
|
||||||
sf_binlog_writer_init_normal_ex(writer, data_path, subdir_name, \
|
|
||||||
SF_BINLOG_FILE_PREFIX_STR, max_record_size, buffer_size, \
|
|
||||||
SF_BINLOG_DEFAULT_ROTATE_SIZE, true)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_init_by_version(writer, data_path, subdir_name, \
|
|
||||||
max_record_size, next_version, buffer_size, ring_size) \
|
|
||||||
sf_binlog_writer_init_by_version_ex(writer, data_path, subdir_name, \
|
|
||||||
SF_BINLOG_FILE_PREFIX_STR, max_record_size, next_version, \
|
|
||||||
buffer_size, ring_size, SF_BINLOG_DEFAULT_ROTATE_SIZE, true)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_init_thread(thread, name, \
|
#define sf_binlog_writer_init_thread(thread, name, \
|
||||||
writer, write_interval_ms, max_delay, max_record_size) \
|
writer, order_by, max_record_size) \
|
||||||
sf_binlog_writer_init_thread_ex(thread, name, writer, \
|
sf_binlog_writer_init_thread_ex(thread, name, writer, \
|
||||||
SF_BINLOG_THREAD_ORDER_MODE_FIXED, write_interval_ms, \
|
SF_BINLOG_THREAD_ORDER_MODE_FIXED, \
|
||||||
max_delay, max_record_size, true, false)
|
order_by, max_record_size, 1, true)
|
||||||
|
|
||||||
static inline int sf_binlog_writer_init_ex(SFBinlogWriterContext *context,
|
static inline int sf_binlog_writer_init(SFBinlogWriterContext *context,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int buffer_size,
|
const int buffer_size, const int max_record_size)
|
||||||
const int write_interval_ms, const int max_delay,
|
|
||||||
const int max_record_size, const bool call_fsync)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
if ((result=sf_binlog_writer_init_normal_ex(&context->writer, data_path,
|
if ((result=sf_binlog_writer_init_normal(&context->writer,
|
||||||
subdir_name, file_prefix, max_record_size, buffer_size,
|
data_path, subdir_name, buffer_size)) != 0)
|
||||||
SF_BINLOG_DEFAULT_ROTATE_SIZE, call_fsync)) != 0)
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return sf_binlog_writer_init_thread(&context->thread, subdir_name,
|
return sf_binlog_writer_init_thread(&context->thread, subdir_name,
|
||||||
&context->writer, write_interval_ms, max_delay, max_record_size);
|
&context->writer, SF_BINLOG_THREAD_TYPE_ORDER_BY_NONE,
|
||||||
}
|
max_record_size);
|
||||||
|
|
||||||
#define sf_binlog_writer_init(context, data_path, subdir_name, \
|
|
||||||
buffer_size, write_interval_ms, max_delay, max_record_size) \
|
|
||||||
sf_binlog_writer_init_ex(context, data_path, subdir_name, \
|
|
||||||
SF_BINLOG_FILE_PREFIX_STR, buffer_size, write_interval_ms, \
|
|
||||||
max_delay, max_record_size, true)
|
|
||||||
|
|
||||||
void sf_binlog_writer_finish(SFBinlogWriterInfo *writer);
|
|
||||||
|
|
||||||
static inline void sf_binlog_writer_destroy_writer(
|
|
||||||
SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
sf_file_writer_destroy(&writer->fw);
|
|
||||||
if (writer->version_ctx.ring.slots != NULL) {
|
|
||||||
free(writer->version_ctx.ring.slots);
|
|
||||||
writer->version_ctx.ring.slots = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_binlog_writer_destroy_thread(
|
|
||||||
SFBinlogWriterThread *thread)
|
|
||||||
{
|
|
||||||
fast_mblock_destroy(&thread->mblock);
|
|
||||||
fc_queue_destroy(&thread->queue);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_binlog_writer_destroy(
|
|
||||||
SFBinlogWriterContext *context)
|
|
||||||
{
|
|
||||||
sf_binlog_writer_finish(&context->writer);
|
|
||||||
sf_binlog_writer_destroy_writer(&context->writer);
|
|
||||||
sf_binlog_writer_destroy_thread(&context->thread);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_binlog_writer_change_order_by(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_change_order_by(SFBinlogWriterInfo *writer,
|
||||||
const short order_by);
|
const short order_by);
|
||||||
|
|
||||||
int sf_binlog_writer_change_passive_write(SFBinlogWriterInfo *writer,
|
|
||||||
const bool passive_write);
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_call_fsync(SFBinlogWriterInfo *writer,
|
|
||||||
const bool call_fsync);
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_next_version(SFBinlogWriterInfo *writer,
|
int sf_binlog_writer_change_next_version(SFBinlogWriterInfo *writer,
|
||||||
const int64_t next_version);
|
const int64_t next_version);
|
||||||
|
|
||||||
static inline int64_t sf_binlog_writer_get_next_version(
|
|
||||||
SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
return writer->version_ctx.next;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_binlog_writer_get_waiting_count(
|
|
||||||
SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
return writer->version_ctx.ring.waiting_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_binlog_writer_get_thread_waiting_count(
|
|
||||||
SFBinlogWriterThread *thread)
|
|
||||||
{
|
|
||||||
int waiting_count;
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&thread->flow_ctrol.lcp.lock);
|
|
||||||
waiting_count = thread->flow_ctrol.waiting_count;
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&thread->flow_ctrol.lcp.lock);
|
|
||||||
|
|
||||||
return waiting_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_rotate_file_ex(SFBinlogWriterInfo *writer,
|
|
||||||
const bool skip_empty_file);
|
|
||||||
|
|
||||||
static inline int sf_binlog_writer_rotate_file(SFBinlogWriterInfo *writer)
|
|
||||||
{
|
|
||||||
const bool skip_empty_file = false;
|
|
||||||
return sf_binlog_writer_rotate_file_ex(writer, skip_empty_file);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_binlog_writer_flush_file(SFBinlogWriterInfo *writer);
|
|
||||||
|
|
||||||
int sf_binlog_writer_change_write_index(SFBinlogWriterInfo *writer,
|
|
||||||
const int write_index);
|
|
||||||
|
|
||||||
int sf_binlog_writer_notify_exit(SFBinlogWriterInfo *writer);
|
|
||||||
|
|
||||||
#define sf_binlog_writer_set_flags(writer, flags) \
|
#define sf_binlog_writer_set_flags(writer, flags) \
|
||||||
sf_file_writer_set_flags(&(writer)->fw, flags)
|
sf_file_writer_set_flags(&(writer)->fw, flags)
|
||||||
|
|
||||||
#define sf_binlog_writer_set_write_done_callback(writer, callback, args) \
|
|
||||||
sf_file_writer_set_write_done_callback(&(writer)->fw, callback, args)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_last_version_ex(writer, log_level) \
|
|
||||||
sf_file_writer_get_last_version_ex(&(writer)->fw, log_level)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_last_version(writer) \
|
#define sf_binlog_writer_get_last_version(writer) \
|
||||||
sf_file_writer_get_last_version(&(writer)->fw)
|
sf_file_writer_get_last_version(&(writer)->fw)
|
||||||
|
|
||||||
#define sf_binlog_writer_get_last_version_silence(writer) \
|
void sf_binlog_writer_finish(SFBinlogWriterInfo *writer);
|
||||||
sf_file_writer_get_last_version_silence(&(writer)->fw)
|
|
||||||
|
|
||||||
#define sf_binlog_get_indexes(writer, start_index, last_index) \
|
|
||||||
sf_file_writer_get_indexes(&(writer)->fw, start_index, last_index)
|
|
||||||
|
|
||||||
#define sf_binlog_get_start_index(writer) \
|
|
||||||
sf_file_writer_get_start_index(&(writer)->fw)
|
|
||||||
|
|
||||||
#define sf_binlog_get_last_index(writer) \
|
|
||||||
sf_file_writer_get_last_index(&(writer)->fw)
|
|
||||||
|
|
||||||
#define sf_binlog_get_current_write_index(writer) \
|
#define sf_binlog_get_current_write_index(writer) \
|
||||||
sf_file_writer_get_current_write_index(&(writer)->fw)
|
sf_file_writer_get_current_index(&(writer)->fw)
|
||||||
|
|
||||||
#define sf_binlog_get_current_write_position(writer, position) \
|
#define sf_binlog_get_current_write_position(writer, position) \
|
||||||
sf_file_writer_get_current_position(&(writer)->fw, position)
|
sf_file_writer_get_current_position(&(writer)->fw, position)
|
||||||
|
|
@ -284,14 +155,7 @@ int sf_binlog_writer_notify_exit(SFBinlogWriterInfo *writer);
|
||||||
static inline SFBinlogWriterBuffer *sf_binlog_writer_alloc_buffer(
|
static inline SFBinlogWriterBuffer *sf_binlog_writer_alloc_buffer(
|
||||||
SFBinlogWriterThread *thread)
|
SFBinlogWriterThread *thread)
|
||||||
{
|
{
|
||||||
SFBinlogWriterBuffer *buffer;
|
return (SFBinlogWriterBuffer *)fast_mblock_alloc_object(&thread->mblock);
|
||||||
|
|
||||||
if ((buffer=(SFBinlogWriterBuffer *)fast_mblock_alloc_object(
|
|
||||||
&thread->mblock)) != NULL)
|
|
||||||
{
|
|
||||||
buffer->type = SF_BINLOG_BUFFER_TYPE_WRITE_TO_FILE;
|
|
||||||
}
|
|
||||||
return buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_binlog_writer_alloc_one_version_buffer(writer, version) \
|
#define sf_binlog_writer_alloc_one_version_buffer(writer, version) \
|
||||||
|
|
@ -308,7 +172,6 @@ static inline SFBinlogWriterBuffer *sf_binlog_writer_alloc_versioned_buffer_ex(
|
||||||
const int64_t last_version, const int type)
|
const int64_t last_version, const int type)
|
||||||
{
|
{
|
||||||
SFBinlogWriterBuffer *buffer;
|
SFBinlogWriterBuffer *buffer;
|
||||||
|
|
||||||
buffer = (SFBinlogWriterBuffer *)fast_mblock_alloc_object(
|
buffer = (SFBinlogWriterBuffer *)fast_mblock_alloc_object(
|
||||||
&writer->thread->mblock);
|
&writer->thread->mblock);
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
|
|
@ -320,16 +183,8 @@ static inline SFBinlogWriterBuffer *sf_binlog_writer_alloc_versioned_buffer_ex(
|
||||||
return buffer;
|
return buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_push_to_binlog_write_queue(SFBinlogWriterInfo *writer,
|
#define sf_binlog_writer_get_filepath(data_path, subdir_name, filename, size) \
|
||||||
SFBinlogWriterBuffer *buffer);
|
sf_file_writer_get_filepath(data_path, subdir_name, filename, size)
|
||||||
|
|
||||||
#define sf_binlog_writer_get_filepath(data_path, subdir_name, filepath, size) \
|
|
||||||
sf_file_writer_get_filepath(data_path, subdir_name, filepath, size)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_filename_ex(data_path, subdir_name, \
|
|
||||||
file_prefix, binlog_index, filename, size) \
|
|
||||||
sf_file_writer_get_filename_ex(data_path, subdir_name, \
|
|
||||||
file_prefix, binlog_index, filename, size)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_filename(data_path, \
|
#define sf_binlog_writer_get_filename(data_path, \
|
||||||
subdir_name, binlog_index, filename, size) \
|
subdir_name, binlog_index, filename, size) \
|
||||||
|
|
@ -341,29 +196,18 @@ void sf_push_to_binlog_write_queue(SFBinlogWriterInfo *writer,
|
||||||
sf_file_writer_get_index_filename(data_path, \
|
sf_file_writer_get_index_filename(data_path, \
|
||||||
subdir_name, filename, size)
|
subdir_name, filename, size)
|
||||||
|
|
||||||
#define sf_binlog_writer_get_binlog_indexes(data_path, \
|
#define sf_binlog_writer_set_binlog_index(writer, binlog_index) \
|
||||||
subdir_name, start_index, last_index) \
|
sf_file_writer_set_binlog_index(&(writer)->fw, binlog_index)
|
||||||
sf_file_writer_get_binlog_indexes(data_path, \
|
|
||||||
subdir_name, start_index, last_index)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_binlog_start_index(data_path, \
|
#define sf_push_to_binlog_thread_queue(thread, buffer) \
|
||||||
subdir_name, start_index) \
|
fc_queue_push(&(thread)->queue, buffer)
|
||||||
sf_file_writer_get_binlog_start_index(data_path, \
|
|
||||||
subdir_name, start_index)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_binlog_last_index(data_path, \
|
static inline void sf_push_to_binlog_write_queue(SFBinlogWriterInfo *writer,
|
||||||
subdir_name, last_index) \
|
SFBinlogWriterBuffer *buffer)
|
||||||
sf_file_writer_get_binlog_last_index(data_path, \
|
{
|
||||||
subdir_name, last_index)
|
buffer->type = SF_BINLOG_BUFFER_TYPE_WRITE_TO_FILE;
|
||||||
|
fc_queue_push(&writer->thread->queue, buffer);
|
||||||
#define sf_binlog_set_indexes(writer, start_index, last_index) \
|
}
|
||||||
sf_file_writer_set_indexes(&(writer)->fw, start_index, last_index)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_set_binlog_start_index(writer, start_index) \
|
|
||||||
sf_file_writer_set_binlog_start_index(&(writer)->fw, start_index)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_set_binlog_write_index(writer, last_index) \
|
|
||||||
sf_file_writer_set_binlog_write_index(&(writer)->fw, last_index)
|
|
||||||
|
|
||||||
#define sf_binlog_writer_get_last_lines(data_path, subdir_name, \
|
#define sf_binlog_writer_get_last_lines(data_path, subdir_name, \
|
||||||
current_write_index, buff, buff_size, count, length) \
|
current_write_index, buff, buff_size, count, length) \
|
||||||
|
|
|
||||||
|
|
@ -1,106 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License, version 3
|
|
||||||
* or later ("AGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//sf_buffered_writer.h
|
|
||||||
|
|
||||||
#ifndef _SF_BUFFERED_WRITER_H_
|
|
||||||
#define _SF_BUFFERED_WRITER_H_
|
|
||||||
|
|
||||||
#include "sf_types.h"
|
|
||||||
#include "sf_func.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int fd;
|
|
||||||
const char *filename;
|
|
||||||
SFBinlogBuffer buffer;
|
|
||||||
} SFBufferedWriter;
|
|
||||||
|
|
||||||
#define sf_buffered_writer_init(writer, filename) \
|
|
||||||
sf_buffered_writer_init_ex(writer, filename, 1024 * 1024)
|
|
||||||
|
|
||||||
#define SF_BUFFERED_WRITER_LENGTH(bw) \
|
|
||||||
SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH((bw).buffer)
|
|
||||||
|
|
||||||
#define SF_BUFFERED_WRITER_REMAIN(bw) \
|
|
||||||
SF_BINLOG_BUFFER_PRODUCER_BUFF_REMAIN((bw).buffer)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int sf_buffered_writer_init_ex(SFBufferedWriter *writer,
|
|
||||||
const char *filename, const int buffer_size)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
writer->filename = filename;
|
|
||||||
writer->fd = open(filename, O_WRONLY | O_CREAT |
|
|
||||||
O_TRUNC | O_CLOEXEC, 0644);
|
|
||||||
if (writer->fd < 0) {
|
|
||||||
result = errno != 0 ? errno : EIO;
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"open file %s fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, filename, result, STRERROR(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result=sf_binlog_buffer_init(&writer->buffer, buffer_size)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_buffered_writer_save(SFBufferedWriter *writer)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
int length;
|
|
||||||
|
|
||||||
length = writer->buffer.data_end - writer->buffer.buff;
|
|
||||||
if (fc_safe_write(writer->fd, writer->buffer.buff, length) != length) {
|
|
||||||
result = errno != 0 ? errno : EIO;
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"write to file %s fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, writer->filename, result, STRERROR(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
writer->buffer.data_end = writer->buffer.buff;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_buffered_writer_destroy(SFBufferedWriter *writer)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (writer->fd >= 0) {
|
|
||||||
if (fsync(writer->fd) != 0) {
|
|
||||||
result = errno != 0 ? errno : EIO;
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"fsync to file %s fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, writer->filename, result, STRERROR(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
close(writer->fd);
|
|
||||||
writer->fd = -1;
|
|
||||||
}
|
|
||||||
sf_binlog_buffer_destroy(&writer->buffer);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -23,7 +23,7 @@ static int calc_cluster_config_sign(SFClusterConfig *cluster)
|
||||||
FastBuffer buffer;
|
FastBuffer buffer;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result=fast_buffer_init1(&buffer, 1024)) != 0) {
|
if ((result=fast_buffer_init_ex(&buffer, 1024)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
fc_server_to_config_string(&cluster->server_cfg, &buffer);
|
fc_server_to_config_string(&cluster->server_cfg, &buffer);
|
||||||
|
|
@ -116,19 +116,19 @@ int sf_load_cluster_config_by_file(SFClusterConfig *cluster,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_cluster_config_ex1(SFClusterConfig *cluster,
|
int sf_load_cluster_config_ex(SFClusterConfig *cluster, IniFullContext
|
||||||
IniFullContext *ini_ctx, const char *cluster_config_item_name,
|
*ini_ctx, const int default_port, char *full_cluster_filename,
|
||||||
const int default_port, char *full_cluster_filename, const int size)
|
const int size)
|
||||||
{
|
{
|
||||||
const bool share_between_groups = true;
|
const bool share_between_groups = true;
|
||||||
char *cluster_config_filename;
|
char *cluster_config_filename;
|
||||||
|
|
||||||
cluster_config_filename = iniGetStrValue(ini_ctx->section_name,
|
cluster_config_filename = iniGetStrValue(ini_ctx->section_name,
|
||||||
cluster_config_item_name, ini_ctx->context);
|
"cluster_config_filename", ini_ctx->context);
|
||||||
if (cluster_config_filename == NULL || *cluster_config_filename == '\0') {
|
if (cluster_config_filename == NULL || *cluster_config_filename == '\0') {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"config file: %s, item \"%s\" not exist or empty",
|
"config file: %s, item \"cluster_config_filename\" "
|
||||||
__LINE__, cluster_config_item_name, ini_ctx->filename);
|
"not exist or empty", __LINE__, ini_ctx->filename);
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,29 +23,9 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sf_load_cluster_config_ex1(SFClusterConfig *cluster,
|
int sf_load_cluster_config_ex(SFClusterConfig *cluster, IniFullContext
|
||||||
IniFullContext *ini_ctx, const char *cluster_config_item_name,
|
*ini_ctx, const int default_port, char *full_cluster_filename,
|
||||||
const int default_port, char *full_cluster_filename, const int size);
|
const int size);
|
||||||
|
|
||||||
static inline int sf_load_cluster_config_ex(SFClusterConfig *cluster,
|
|
||||||
IniFullContext *ini_ctx, const int default_port,
|
|
||||||
char *full_cluster_filename, const int size)
|
|
||||||
{
|
|
||||||
const char *cluster_config_item_name = "cluster_config_filename";
|
|
||||||
return sf_load_cluster_config_ex1(cluster, ini_ctx,
|
|
||||||
cluster_config_item_name, default_port,
|
|
||||||
full_cluster_filename, PATH_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_load_cluster_config1(SFClusterConfig *cluster,
|
|
||||||
IniFullContext *ini_ctx, const char *cluster_config_item_name,
|
|
||||||
const int default_port)
|
|
||||||
{
|
|
||||||
char full_cluster_filename[PATH_MAX];
|
|
||||||
return sf_load_cluster_config_ex1(cluster, ini_ctx,
|
|
||||||
cluster_config_item_name, default_port,
|
|
||||||
full_cluster_filename, PATH_MAX);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_load_cluster_config(SFClusterConfig *cluster,
|
static inline int sf_load_cluster_config(SFClusterConfig *cluster,
|
||||||
IniFullContext *ini_ctx, const int default_port)
|
IniFullContext *ini_ctx, const int default_port)
|
||||||
|
|
|
||||||
|
|
@ -25,10 +25,10 @@
|
||||||
#include "fastcommon/logger.h"
|
#include "fastcommon/logger.h"
|
||||||
#include "sf_configs.h"
|
#include "sf_configs.h"
|
||||||
|
|
||||||
#define DEFAULT_RETRY_MAX_INTERVAL_MS 3000
|
#define DEFAULT_RETRY_MAX_INTERVAL_MS 5000
|
||||||
#define DEFAULT_CONNECT_RETRY_TIMES 200
|
#define DEFAULT_CONNECT_RETRY_TIMES 10
|
||||||
#define DEFAULT_CONNECT_RETRY_INTERVAL_MS 100
|
#define DEFAULT_CONNECT_RETRY_INTERVAL_MS 100
|
||||||
#define DEFAULT_NETWORK_RETRY_TIMES 200
|
#define DEFAULT_NETWORK_RETRY_TIMES 10
|
||||||
#define DEFAULT_NETWORK_RETRY_INTERVAL_MS 100
|
#define DEFAULT_NETWORK_RETRY_INTERVAL_MS 100
|
||||||
|
|
||||||
int sf_load_net_retry_config(SFNetRetryConfig *net_retry_cfg,
|
int sf_load_net_retry_config(SFNetRetryConfig *net_retry_cfg,
|
||||||
|
|
@ -94,14 +94,13 @@ void sf_net_retry_config_to_string(SFNetRetryConfig *net_retry_cfg,
|
||||||
net_retry_cfg->network.interval_ms);
|
net_retry_cfg->network.interval_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_read_rule_config_ex(SFDataReadRule *rule,
|
void sf_load_read_rule_config_ex(SFDataReadRule *rule,
|
||||||
IniFullContext *ini_ctx, const SFDataReadRule def_rule)
|
IniFullContext *ini_ctx, const SFDataReadRule def_rule)
|
||||||
{
|
{
|
||||||
char *read_rule;
|
char *read_rule;
|
||||||
|
|
||||||
read_rule = iniGetStrValueEx(ini_ctx->section_name,
|
read_rule = iniGetStrValueEx(ini_ctx->section_name,
|
||||||
"read_rule", ini_ctx->context, true);
|
"read_rule", ini_ctx->context, true);
|
||||||
if (read_rule == NULL) {
|
if (read_rule == NULL || *read_rule == '\0') {
|
||||||
*rule = def_rule;
|
*rule = def_rule;
|
||||||
} else if (strncasecmp(read_rule, "any", 3) == 0) {
|
} else if (strncasecmp(read_rule, "any", 3) == 0) {
|
||||||
*rule = sf_data_read_rule_any_available;
|
*rule = sf_data_read_rule_any_available;
|
||||||
|
|
@ -111,62 +110,8 @@ int sf_load_read_rule_config_ex(SFDataReadRule *rule,
|
||||||
*rule = sf_data_read_rule_master_only;
|
*rule = sf_data_read_rule_master_only;
|
||||||
} else {
|
} else {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"config file: %s, unkown read_rule: %s",
|
"config file: %s, unkown read_rule: %s, set to any",
|
||||||
__LINE__, ini_ctx->filename, read_rule);
|
__LINE__, ini_ctx->filename, read_rule);
|
||||||
return EINVAL;
|
*rule = sf_data_read_rule_any_available;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_load_election_quorum_config_ex(SFElectionQuorum *quorum,
|
|
||||||
IniFullContext *ini_ctx, const SFElectionQuorum def_quorum)
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
str = iniGetStrValue(ini_ctx->section_name,
|
|
||||||
"quorum", ini_ctx->context);
|
|
||||||
if (str == NULL) {
|
|
||||||
*quorum = def_quorum;
|
|
||||||
} else if (strncasecmp(str, "auto", 4) == 0) {
|
|
||||||
*quorum = sf_election_quorum_auto;
|
|
||||||
} else if (strncasecmp(str, "any", 3) == 0) {
|
|
||||||
*quorum = sf_election_quorum_any;
|
|
||||||
} else if (strncasecmp(str, "majority", 8) == 0) {
|
|
||||||
*quorum = sf_election_quorum_majority;
|
|
||||||
} else {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"config file: %s, unkown quorum: %s",
|
|
||||||
__LINE__, ini_ctx->filename, str);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_load_replication_quorum_config_ex(SFReplicationQuorum *quorum,
|
|
||||||
IniFullContext *ini_ctx, const SFReplicationQuorum def_quorum)
|
|
||||||
{
|
|
||||||
char *str;
|
|
||||||
|
|
||||||
str = iniGetStrValue(ini_ctx->section_name,
|
|
||||||
"quorum", ini_ctx->context);
|
|
||||||
if (str == NULL) {
|
|
||||||
*quorum = def_quorum;
|
|
||||||
} else if (strncasecmp(str, "auto", 4) == 0) {
|
|
||||||
*quorum = sf_replication_quorum_auto;
|
|
||||||
} else if (strncasecmp(str, "any", 3) == 0) {
|
|
||||||
*quorum = sf_replication_quorum_any;
|
|
||||||
} else if (strncasecmp(str, "majority", 8) == 0) {
|
|
||||||
*quorum = sf_replication_quorum_majority;
|
|
||||||
} else if (strncasecmp(str, "smart", 5) == 0) {
|
|
||||||
*quorum = sf_replication_quorum_smart;
|
|
||||||
} else {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"config file: %s, unkown quorum: %s",
|
|
||||||
__LINE__, ini_ctx->filename, str);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
106
src/sf_configs.h
106
src/sf_configs.h
|
|
@ -67,7 +67,7 @@ static inline int sf_calc_next_retry_interval(SFNetRetryIntervalContext *ctx)
|
||||||
return ctx->interval_ms;
|
return ctx->interval_ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_read_rule_config_ex(SFDataReadRule *rule,
|
void sf_load_read_rule_config_ex(SFDataReadRule *rule,
|
||||||
IniFullContext *ini_ctx, const SFDataReadRule def_rule);
|
IniFullContext *ini_ctx, const SFDataReadRule def_rule);
|
||||||
|
|
||||||
static inline const char *sf_get_read_rule_caption(
|
static inline const char *sf_get_read_rule_caption(
|
||||||
|
|
@ -85,113 +85,9 @@ static inline const char *sf_get_read_rule_caption(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_election_quorum_config_ex(SFElectionQuorum *quorum,
|
|
||||||
IniFullContext *ini_ctx, const SFElectionQuorum def_quorum);
|
|
||||||
|
|
||||||
static inline const char *sf_get_election_quorum_caption(
|
|
||||||
const SFElectionQuorum quorum)
|
|
||||||
{
|
|
||||||
switch (quorum) {
|
|
||||||
case sf_election_quorum_auto:
|
|
||||||
return "auto";
|
|
||||||
case sf_election_quorum_any:
|
|
||||||
return "any";
|
|
||||||
case sf_election_quorum_majority:
|
|
||||||
return "majority";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool sf_election_quorum_check(const SFElectionQuorum quorum,
|
|
||||||
const bool vote_node_enabled, const int total_count,
|
|
||||||
const int active_count)
|
|
||||||
{
|
|
||||||
switch (quorum) {
|
|
||||||
case sf_election_quorum_any:
|
|
||||||
return active_count > 0;
|
|
||||||
case sf_election_quorum_auto:
|
|
||||||
if (total_count % 2 == 0 && !vote_node_enabled) {
|
|
||||||
return active_count > 0; //same as sf_election_quorum_any
|
|
||||||
}
|
|
||||||
//continue
|
|
||||||
case sf_election_quorum_majority:
|
|
||||||
if (active_count == total_count) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return active_count > total_count / 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_load_replication_quorum_config_ex(SFReplicationQuorum *quorum,
|
|
||||||
IniFullContext *ini_ctx, const SFReplicationQuorum def_quorum);
|
|
||||||
|
|
||||||
static inline const char *sf_get_replication_quorum_caption(
|
|
||||||
const SFReplicationQuorum quorum)
|
|
||||||
{
|
|
||||||
switch (quorum) {
|
|
||||||
case sf_replication_quorum_auto:
|
|
||||||
return "auto";
|
|
||||||
case sf_replication_quorum_any:
|
|
||||||
return "any";
|
|
||||||
case sf_replication_quorum_majority:
|
|
||||||
return "majority";
|
|
||||||
case sf_replication_quorum_smart:
|
|
||||||
return "smart";
|
|
||||||
default:
|
|
||||||
return "unknown";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SF_REPLICATION_QUORUM_MAJORITY(server_count, success_count) \
|
|
||||||
((success_count == server_count) || (success_count > server_count / 2))
|
|
||||||
|
|
||||||
static inline bool sf_replication_quorum_check(const SFReplicationQuorum
|
|
||||||
quorum, const int server_count, const int success_count)
|
|
||||||
{
|
|
||||||
switch (quorum) {
|
|
||||||
case sf_replication_quorum_any:
|
|
||||||
return true;
|
|
||||||
case sf_replication_quorum_auto:
|
|
||||||
if (server_count % 2 == 0) {
|
|
||||||
return true; //same as sf_replication_quorum_any
|
|
||||||
}
|
|
||||||
//continue
|
|
||||||
case sf_replication_quorum_smart:
|
|
||||||
case sf_replication_quorum_majority:
|
|
||||||
return SF_REPLICATION_QUORUM_MAJORITY(
|
|
||||||
server_count, success_count);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define sf_load_read_rule_config(rule, ini_ctx) \
|
#define sf_load_read_rule_config(rule, ini_ctx) \
|
||||||
sf_load_read_rule_config_ex(rule, ini_ctx, sf_data_read_rule_master_only)
|
sf_load_read_rule_config_ex(rule, ini_ctx, sf_data_read_rule_master_only)
|
||||||
|
|
||||||
#define sf_load_election_quorum_config(quorum, ini_ctx) \
|
|
||||||
sf_load_election_quorum_config_ex(quorum, ini_ctx, sf_election_quorum_auto)
|
|
||||||
|
|
||||||
#define sf_load_replication_quorum_config(quorum, ini_ctx) \
|
|
||||||
sf_load_replication_quorum_config_ex(quorum, ini_ctx, \
|
|
||||||
sf_replication_quorum_auto)
|
|
||||||
|
|
||||||
#define SF_ELECTION_QUORUM_NEED_REQUEST_VOTE_NODE(quorum, \
|
|
||||||
vote_node_enabled, server_count, active_count) \
|
|
||||||
(active_count < server_count && vote_node_enabled && \
|
|
||||||
quorum != sf_election_quorum_any && server_count % 2 == 0)
|
|
||||||
|
|
||||||
#define SF_ELECTION_QUORUM_NEED_CHECK_VOTE_NODE(quorum, \
|
|
||||||
vote_node_enabled, server_count) \
|
|
||||||
(vote_node_enabled && quorum != sf_election_quorum_any \
|
|
||||||
&& server_count % 2 == 0)
|
|
||||||
|
|
||||||
#define SF_REPLICATION_QUORUM_NEED_MAJORITY(quorum, server_count) \
|
|
||||||
(server_count > 1 && (quorum != sf_replication_quorum_any))
|
|
||||||
|
|
||||||
#define SF_REPLICATION_QUORUM_NEED_DETECT(quorum, server_count) \
|
|
||||||
(server_count % 2 == 0 && (quorum == sf_replication_quorum_smart || \
|
|
||||||
quorum == sf_replication_quorum_auto))
|
|
||||||
|
|
||||||
#define SF_NET_RETRY_FINISHED(retry_times, counter, result) \
|
#define SF_NET_RETRY_FINISHED(retry_times, counter, result) \
|
||||||
!((SF_IS_RETRIABLE_ERROR(result) && ((retry_times > 0 && \
|
!((SF_IS_RETRIABLE_ERROR(result) && ((retry_times > 0 && \
|
||||||
counter <= retry_times) || (retry_times < 0))))
|
counter <= retry_times) || (retry_times < 0))))
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,13 @@ static int get_group_servers(SFConnectionManager *cm,
|
||||||
SFCMConnGroupEntry *group);
|
SFCMConnGroupEntry *group);
|
||||||
|
|
||||||
static ConnectionInfo *get_spec_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_spec_connection(SFConnectionManager *cm,
|
||||||
const ConnectionInfo *target, const bool shared, int *err_no)
|
const ConnectionInfo *target, int *err_no)
|
||||||
{
|
{
|
||||||
return conn_pool_get_connection_ex(&cm->cpool,
|
return conn_pool_get_connection(&cm->cpool, target, err_no);
|
||||||
target, cm->module_name, shared, err_no);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *make_connection(SFConnectionManager *cm,
|
static ConnectionInfo *make_connection(SFConnectionManager *cm,
|
||||||
FCAddressPtrArray *addr_array, const bool shared, int *err_no)
|
FCAddressPtrArray *addr_array, int *err_no)
|
||||||
{
|
{
|
||||||
FCAddressInfo **current;
|
FCAddressInfo **current;
|
||||||
FCAddressInfo **addr;
|
FCAddressInfo **addr;
|
||||||
|
|
@ -56,7 +55,7 @@ static ConnectionInfo *make_connection(SFConnectionManager *cm,
|
||||||
|
|
||||||
current = addr_array->addrs + addr_array->index;
|
current = addr_array->addrs + addr_array->index;
|
||||||
if ((conn=get_spec_connection(cm, &(*current)->conn,
|
if ((conn=get_spec_connection(cm, &(*current)->conn,
|
||||||
shared, err_no)) != NULL)
|
err_no)) != NULL)
|
||||||
{
|
{
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
@ -72,7 +71,7 @@ static ConnectionInfo *make_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((conn=get_spec_connection(cm, &(*addr)->conn,
|
if ((conn=get_spec_connection(cm, &(*addr)->conn,
|
||||||
shared, err_no)) != NULL)
|
err_no)) != NULL)
|
||||||
{
|
{
|
||||||
addr_array->index = addr - addr_array->addrs;
|
addr_array->index = addr - addr_array->addrs;
|
||||||
return conn;
|
return conn;
|
||||||
|
|
@ -83,22 +82,22 @@ static ConnectionInfo *make_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *get_server_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_server_connection(SFConnectionManager *cm,
|
||||||
FCServerInfo *server, const bool shared, int *err_no)
|
FCServerInfo *server, int *err_no)
|
||||||
{
|
{
|
||||||
FCAddressPtrArray *addr_array;
|
FCAddressPtrArray *addr_array;
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
|
|
||||||
addr_array = &server->group_addrs[cm->server_group_index].address_array;
|
addr_array = &server->group_addrs[cm->server_group_index].address_array;
|
||||||
if ((conn=make_connection(cm, addr_array, shared, err_no)) == NULL) {
|
if ((conn=make_connection(cm, addr_array, err_no)) == NULL) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s server id: %d, address count: %d, get_server_connection fail",
|
"server id: %d, get_server_connection fail",
|
||||||
__LINE__, cm->module_name, server->id, addr_array->count);
|
__LINE__, server->id);
|
||||||
}
|
}
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *get_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_connection(SFConnectionManager *cm,
|
||||||
const int group_index, const bool shared, int *err_no)
|
const int group_index, int *err_no)
|
||||||
{
|
{
|
||||||
SFCMServerArray *server_array;
|
SFCMServerArray *server_array;
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
|
|
@ -110,7 +109,7 @@ static ConnectionInfo *get_connection(SFConnectionManager *cm,
|
||||||
server_hash_code = rand();
|
server_hash_code = rand();
|
||||||
server_index = server_hash_code % server_array->count;
|
server_index = server_hash_code % server_array->count;
|
||||||
if ((conn=make_connection(cm, server_array->servers[server_index].
|
if ((conn=make_connection(cm, server_array->servers[server_index].
|
||||||
addr_array, shared, err_no)) != NULL)
|
addr_array, err_no)) != NULL)
|
||||||
{
|
{
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +121,7 @@ static ConnectionInfo *get_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((conn=make_connection(cm, server_array->servers[i].
|
if ((conn=make_connection(cm, server_array->servers[i].
|
||||||
addr_array, shared, err_no)) != NULL)
|
addr_array, err_no)) != NULL)
|
||||||
{
|
{
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
@ -130,8 +129,8 @@ static ConnectionInfo *get_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s data group index: %d, get_connection fail, "
|
"data group index: %d, get_connection fail, "
|
||||||
"configured server count: %d", __LINE__, cm->module_name,
|
"configured server count: %d", __LINE__,
|
||||||
group_index, server_array->count);
|
group_index, server_array->count);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -145,6 +144,33 @@ static inline void set_connection_params(ConnectionInfo *conn,
|
||||||
cparam->cm.old_alives = old_alives;
|
cparam->cm.old_alives = old_alives;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline ConnectionInfo *make_master_connection(SFConnectionManager *cm,
|
||||||
|
SFCMConnGroupEntry *group, int *err_no)
|
||||||
|
{
|
||||||
|
SFCMServerEntry *master;
|
||||||
|
ConnectionInfo *conn;
|
||||||
|
|
||||||
|
master = (SFCMServerEntry *)FC_ATOMIC_GET(group->master);
|
||||||
|
if (master != NULL) {
|
||||||
|
if ((conn=make_connection(cm, master->addr_array,
|
||||||
|
err_no)) != NULL)
|
||||||
|
{
|
||||||
|
if (cm->common_cfg->read_rule == sf_data_read_rule_master_only) {
|
||||||
|
set_connection_params(conn, master, NULL);
|
||||||
|
} else {
|
||||||
|
SFCMServerPtrArray *alives;
|
||||||
|
alives = (SFCMServerPtrArray *)FC_ATOMIC_GET(group->alives);
|
||||||
|
set_connection_params(conn, master, alives);
|
||||||
|
}
|
||||||
|
return conn;
|
||||||
|
}
|
||||||
|
|
||||||
|
__sync_bool_compare_and_swap(&group->master, master, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static inline int push_to_detect_queue(SFConnectionManager *cm,
|
static inline int push_to_detect_queue(SFConnectionManager *cm,
|
||||||
SFCMConnGroupEntry *group, SFCMServerPtrArray *alives)
|
SFCMConnGroupEntry *group, SFCMServerPtrArray *alives)
|
||||||
{
|
{
|
||||||
|
|
@ -176,7 +202,7 @@ static inline bool alive_array_cas(SFConnectionManager *cm,
|
||||||
push_to_detect_queue(cm, group, new_alives);
|
push_to_detect_queue(cm, group, new_alives);
|
||||||
fast_mblock_delay_free_object(&cm->sptr_array_allocator, old_alives,
|
fast_mblock_delay_free_object(&cm->sptr_array_allocator, old_alives,
|
||||||
(cm->common_cfg->connect_timeout + cm->common_cfg->
|
(cm->common_cfg->connect_timeout + cm->common_cfg->
|
||||||
network_timeout) * group->all.count * 4);
|
network_timeout) * group->all.count);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
fast_mblock_free_object(&cm->sptr_array_allocator, new_alives);
|
fast_mblock_free_object(&cm->sptr_array_allocator, new_alives);
|
||||||
|
|
@ -224,42 +250,14 @@ static int remove_from_alives(SFConnectionManager *cm,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline ConnectionInfo *make_master_connection(SFConnectionManager *cm,
|
|
||||||
SFCMConnGroupEntry *group, const bool shared, int *err_no)
|
|
||||||
{
|
|
||||||
SFCMServerEntry *master;
|
|
||||||
ConnectionInfo *conn;
|
|
||||||
SFCMServerPtrArray *alives;
|
|
||||||
|
|
||||||
master = (SFCMServerEntry *)FC_ATOMIC_GET(group->master);
|
|
||||||
if (master != NULL) {
|
|
||||||
if ((conn=make_connection(cm, master->addr_array,
|
|
||||||
shared, err_no)) != NULL)
|
|
||||||
{
|
|
||||||
alives = (SFCMServerPtrArray *)FC_ATOMIC_GET(group->alives);
|
|
||||||
set_connection_params(conn, master, alives);
|
|
||||||
return conn;
|
|
||||||
} else {
|
|
||||||
alives = (SFCMServerPtrArray *)FC_ATOMIC_GET(group->alives);
|
|
||||||
if (alives != NULL) {
|
|
||||||
remove_from_alives(cm, group, alives, master);
|
|
||||||
}
|
|
||||||
__sync_bool_compare_and_swap(&group->master, master, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*err_no = SF_RETRIABLE_ERROR_NO_SERVER;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline ConnectionInfo *make_readable_connection(SFConnectionManager *cm,
|
static inline ConnectionInfo *make_readable_connection(SFConnectionManager *cm,
|
||||||
SFCMConnGroupEntry *group, SFCMServerPtrArray *alives,
|
SFCMConnGroupEntry *group, SFCMServerPtrArray *alives,
|
||||||
const int index, const bool shared, int *err_no)
|
const int index, int *err_no)
|
||||||
{
|
{
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
|
|
||||||
if ((conn=make_connection(cm, alives->servers[index]->
|
if ((conn=make_connection(cm, alives->servers[index]->
|
||||||
addr_array, shared, err_no)) == NULL)
|
addr_array, err_no)) == NULL)
|
||||||
{
|
{
|
||||||
remove_from_alives(cm, group, alives, alives->servers[index]);
|
remove_from_alives(cm, group, alives, alives->servers[index]);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -270,82 +268,72 @@ static inline ConnectionInfo *make_readable_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *get_master_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_master_connection(SFConnectionManager *cm,
|
||||||
const int group_index, const bool shared, int *err_no)
|
const int group_index, int *err_no)
|
||||||
{
|
{
|
||||||
SFCMConnGroupEntry *group;
|
SFCMConnGroupEntry *group;
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
SFNetRetryIntervalContext net_retry_ctx;
|
SFNetRetryIntervalContext net_retry_ctx;
|
||||||
int retry_count;
|
int i;
|
||||||
|
|
||||||
group = cm->groups.entries + group_index;
|
group = cm->groups.entries + group_index;
|
||||||
sf_init_net_retry_interval_context(&net_retry_ctx,
|
sf_init_net_retry_interval_context(&net_retry_ctx,
|
||||||
&cm->common_cfg->net_retry_cfg.interval_mm,
|
&cm->common_cfg->net_retry_cfg.interval_mm,
|
||||||
&cm->common_cfg->net_retry_cfg.connect);
|
&cm->common_cfg->net_retry_cfg.connect);
|
||||||
retry_count = 0;
|
i = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((conn=make_master_connection(cm, group, shared, err_no)) != NULL) {
|
if ((conn=make_master_connection(cm, group, err_no)) != NULL) {
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
logInfo("file: "__FILE__", line: %d, "
|
|
||||||
"retry_count: %d, interval_ms: %d, data group id: %d, "
|
|
||||||
"master: %p, alive count: %d, all count: %d", __LINE__,
|
|
||||||
retry_count, net_retry_ctx.interval_ms, group->id,
|
|
||||||
FC_ATOMIC_GET(group->master), ((SFCMServerPtrArray *)
|
|
||||||
FC_ATOMIC_GET(group->alives))->count, group->all.count);
|
|
||||||
*/
|
|
||||||
|
|
||||||
*err_no = get_group_servers(cm, group);
|
*err_no = get_group_servers(cm, group);
|
||||||
if (*err_no == 0) {
|
if (*err_no == 0) {
|
||||||
*err_no = SF_RETRIABLE_ERROR_NO_SERVER; //for try again
|
*err_no = SF_RETRIABLE_ERROR_NO_SERVER; //for try again
|
||||||
}
|
}
|
||||||
SF_NET_RETRY_CHECK_AND_SLEEP(net_retry_ctx,
|
SF_NET_RETRY_CHECK_AND_SLEEP(net_retry_ctx,
|
||||||
cm->common_cfg->net_retry_cfg.
|
cm->common_cfg->net_retry_cfg.
|
||||||
connect.times, ++retry_count, *err_no);
|
connect.times, ++i, *err_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s get_master_connection fail, group id: %d, "
|
"get_master_connection fail, errno: %d",
|
||||||
"retry count: %d, " "errno: %d", __LINE__,
|
__LINE__, *err_no);
|
||||||
cm->module_name, group->id, retry_count, *err_no);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *get_readable_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_readable_connection(SFConnectionManager *cm,
|
||||||
const int group_index, const bool shared, int *err_no)
|
const int group_index, int *err_no)
|
||||||
{
|
{
|
||||||
SFCMConnGroupEntry *group;
|
SFCMConnGroupEntry *group;
|
||||||
SFCMServerPtrArray *alives;
|
SFCMServerPtrArray *alives;
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
SFNetRetryIntervalContext net_retry_ctx;
|
SFNetRetryIntervalContext net_retry_ctx;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
int retry_count;
|
int i;
|
||||||
|
|
||||||
group = cm->groups.entries + group_index;
|
group = cm->groups.entries + group_index;
|
||||||
if ((cm->common_cfg->read_rule == sf_data_read_rule_master_only) ||
|
if ((cm->common_cfg->read_rule == sf_data_read_rule_master_only) ||
|
||||||
(group->all.count == 1))
|
(group->all.count == 1))
|
||||||
{
|
{
|
||||||
return get_master_connection(cm, group_index, shared, err_no);
|
return get_master_connection(cm, group_index, err_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_init_net_retry_interval_context(&net_retry_ctx,
|
sf_init_net_retry_interval_context(&net_retry_ctx,
|
||||||
&cm->common_cfg->net_retry_cfg.interval_mm,
|
&cm->common_cfg->net_retry_cfg.interval_mm,
|
||||||
&cm->common_cfg->net_retry_cfg.connect);
|
&cm->common_cfg->net_retry_cfg.connect);
|
||||||
retry_count = 0;
|
i = 0;
|
||||||
while (1) {
|
while (1) {
|
||||||
alives = (SFCMServerPtrArray *)FC_ATOMIC_GET(group->alives);
|
alives = (SFCMServerPtrArray *)FC_ATOMIC_GET(group->alives);
|
||||||
if (alives->count > 0) {
|
if (alives->count > 0) {
|
||||||
index = rand() % alives->count;
|
index = rand() % alives->count;
|
||||||
if ((conn=make_readable_connection(cm, group, alives,
|
if ((conn=make_readable_connection(cm, group, alives,
|
||||||
index, shared, err_no)) != NULL)
|
index, err_no)) != NULL)
|
||||||
{
|
{
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cm->common_cfg->read_rule == sf_data_read_rule_slave_first) {
|
if (cm->common_cfg->read_rule == sf_data_read_rule_slave_first) {
|
||||||
if ((conn=make_master_connection(cm, group, shared, err_no)) != NULL) {
|
if ((conn=make_master_connection(cm, group, err_no)) != NULL) {
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -356,12 +344,12 @@ static ConnectionInfo *get_readable_connection(SFConnectionManager *cm,
|
||||||
}
|
}
|
||||||
SF_NET_RETRY_CHECK_AND_SLEEP(net_retry_ctx,
|
SF_NET_RETRY_CHECK_AND_SLEEP(net_retry_ctx,
|
||||||
cm->common_cfg->net_retry_cfg.
|
cm->common_cfg->net_retry_cfg.
|
||||||
connect.times, ++retry_count, *err_no);
|
connect.times, ++i, *err_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s get_readable_connection fail, retry count: %d, errno: %d",
|
"get_readable_connection fail, errno: %d",
|
||||||
__LINE__, cm->module_name, retry_count, *err_no);
|
__LINE__, *err_no);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -388,11 +376,12 @@ static void close_connection(SFConnectionManager *cm, ConnectionInfo *conn)
|
||||||
if (cparam->cm.sentry != NULL) {
|
if (cparam->cm.sentry != NULL) {
|
||||||
server = cparam->cm.sentry;
|
server = cparam->cm.sentry;
|
||||||
group = cm->groups.entries + server->group_index;
|
group = cm->groups.entries + server->group_index;
|
||||||
if (cparam->cm.old_alives != NULL) {
|
if (cparam->cm.old_alives == NULL) {
|
||||||
|
__sync_bool_compare_and_swap(&group->master, server, NULL);
|
||||||
|
} else {
|
||||||
remove_from_alives(cm, group, cparam->cm.old_alives, server);
|
remove_from_alives(cm, group, cparam->cm.old_alives, server);
|
||||||
cparam->cm.old_alives = NULL;
|
cparam->cm.old_alives = NULL;
|
||||||
}
|
}
|
||||||
__sync_bool_compare_and_swap(&group->master, server, NULL);
|
|
||||||
cparam->cm.sentry = NULL;
|
cparam->cm.sentry = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,12 +389,11 @@ static void close_connection(SFConnectionManager *cm, ConnectionInfo *conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ConnectionInfo *get_leader_connection(SFConnectionManager *cm,
|
static ConnectionInfo *get_leader_connection(SFConnectionManager *cm,
|
||||||
FCServerInfo *server, const bool shared, int *err_no)
|
FCServerInfo *server, int *err_no)
|
||||||
{
|
{
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
SFClientServerEntry leader;
|
SFClientServerEntry leader;
|
||||||
SFNetRetryIntervalContext net_retry_ctx;
|
SFNetRetryIntervalContext net_retry_ctx;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
int i;
|
int i;
|
||||||
int connect_fails;
|
int connect_fails;
|
||||||
|
|
||||||
|
|
@ -416,14 +404,14 @@ static ConnectionInfo *get_leader_connection(SFConnectionManager *cm,
|
||||||
while (1) {
|
while (1) {
|
||||||
do {
|
do {
|
||||||
if ((conn=get_server_connection(cm, server,
|
if ((conn=get_server_connection(cm, server,
|
||||||
shared, err_no)) == NULL)
|
err_no)) == NULL)
|
||||||
{
|
{
|
||||||
connect_fails++;
|
connect_fails++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((*err_no=sf_proto_get_leader(conn, cm->module_name, cm->
|
if ((*err_no=sf_proto_get_leader(conn, cm->common_cfg->
|
||||||
common_cfg->network_timeout, &leader)) != 0)
|
network_timeout, &leader)) != 0)
|
||||||
{
|
{
|
||||||
close_connection(cm, conn);
|
close_connection(cm, conn);
|
||||||
break;
|
break;
|
||||||
|
|
@ -433,27 +421,9 @@ static ConnectionInfo *get_leader_connection(SFConnectionManager *cm,
|
||||||
return conn;
|
return conn;
|
||||||
}
|
}
|
||||||
release_connection(cm, conn);
|
release_connection(cm, conn);
|
||||||
|
if ((conn=get_spec_connection(cm,&leader.conn,
|
||||||
if ((conn=get_spec_connection(cm, &leader.conn,
|
err_no)) == NULL)
|
||||||
shared, err_no)) == NULL)
|
|
||||||
{
|
{
|
||||||
if (cm->server_cfg != NULL) {
|
|
||||||
FCServerInfo *ls;
|
|
||||||
if ((ls=fc_server_get_by_id(cm->server_cfg,
|
|
||||||
leader.server_id)) != NULL)
|
|
||||||
{
|
|
||||||
if (ls->group_addrs[cm->server_group_index].
|
|
||||||
address_array.count > 1)
|
|
||||||
{
|
|
||||||
if ((conn=get_server_connection(cm, ls,
|
|
||||||
shared, err_no)) != NULL)
|
|
||||||
{
|
|
||||||
return conn;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -469,13 +439,11 @@ static ConnectionInfo *get_leader_connection(SFConnectionManager *cm,
|
||||||
connect.times, ++i, *err_no);
|
connect.times, ++i, *err_no);
|
||||||
}
|
}
|
||||||
|
|
||||||
format_ip_address(server->group_addrs[cm->server_group_index].
|
|
||||||
address_array.addrs[0]->conn.ip_addr, formatted_ip);
|
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"%s get_leader_connection fail, server id: %d, %s:%u, errno: %d",
|
"get_leader_connection fail, server id: %d, %s:%u, errno: %d",
|
||||||
__LINE__, cm->module_name, server->id, formatted_ip,
|
__LINE__, server->id, server->group_addrs[cm->server_group_index].
|
||||||
server->group_addrs[cm->server_group_index].address_array.
|
address_array.addrs[0]->conn.ip_addr, server->group_addrs[cm->
|
||||||
addrs[0]->conn.port, *err_no);
|
server_group_index].address_array.addrs[0]->conn.port, *err_no);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -495,7 +463,7 @@ int sf_cm_validate_connection_callback(ConnectionInfo *conn, void *args)
|
||||||
if ((result=sf_active_test(conn, &response, cm->common_cfg->
|
if ((result=sf_active_test(conn, &response, cm->common_cfg->
|
||||||
network_timeout)) != 0)
|
network_timeout)) != 0)
|
||||||
{
|
{
|
||||||
sf_log_network_error(&response, conn, cm->module_name, result);
|
sf_log_network_error(&response, conn, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -521,52 +489,21 @@ int sf_connection_manager_init_ex(SFConnectionManager *cm,
|
||||||
const int group_count, const int server_group_index,
|
const int group_count, const int server_group_index,
|
||||||
const int server_count, const int max_count_per_entry,
|
const int server_count, const int max_count_per_entry,
|
||||||
const int max_idle_time, fc_connection_callback_func
|
const int max_idle_time, fc_connection_callback_func
|
||||||
connect_done_callback, void *args, FCServerConfig *server_cfg,
|
connect_done_callback, void *args, const bool bg_thread_enabled)
|
||||||
const bool bg_thread_enabled)
|
|
||||||
{
|
{
|
||||||
struct {
|
const int socket_domain = AF_INET;
|
||||||
ConnectionExtraParams holder;
|
int htable_init_capacity;
|
||||||
ConnectionExtraParams *ptr;
|
|
||||||
} extra_params;
|
|
||||||
FCServerGroupInfo *server_group;
|
|
||||||
|
|
||||||
int htable_capacity;
|
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (server_count <= 4) {
|
htable_init_capacity = 4 * server_count;
|
||||||
htable_capacity = 16;
|
if (htable_init_capacity < 256) {
|
||||||
} else if (server_count <= 16) {
|
htable_init_capacity = 256;
|
||||||
htable_capacity = 64;
|
|
||||||
} else if (server_count <= 32) {
|
|
||||||
htable_capacity = 128;
|
|
||||||
} else if (server_count < 64) {
|
|
||||||
htable_capacity = 256;
|
|
||||||
} else {
|
|
||||||
htable_capacity = 4 * server_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((server_group=fc_server_get_group_by_index(server_cfg,
|
|
||||||
server_group_index)) == NULL)
|
|
||||||
{
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server_group->comm_type == fc_comm_type_sock) {
|
|
||||||
extra_params.ptr = NULL;
|
|
||||||
} else {
|
|
||||||
if ((result=conn_pool_set_rdma_extra_params(&extra_params.holder,
|
|
||||||
server_cfg, server_group_index)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
extra_params.ptr = &extra_params.holder;
|
|
||||||
}
|
}
|
||||||
if ((result=conn_pool_init_ex1(&cm->cpool, common_cfg->connect_timeout,
|
if ((result=conn_pool_init_ex1(&cm->cpool, common_cfg->connect_timeout,
|
||||||
max_count_per_entry, max_idle_time, htable_capacity,
|
max_count_per_entry, max_idle_time, socket_domain,
|
||||||
connect_done_callback, args,
|
htable_init_capacity, connect_done_callback, args,
|
||||||
sf_cm_validate_connection_callback, cm,
|
sf_cm_validate_connection_callback, cm,
|
||||||
sizeof(SFConnectionParameters),
|
sizeof(SFConnectionParameters))) != 0)
|
||||||
extra_params.ptr)) != 0)
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -586,11 +523,9 @@ int sf_connection_manager_init_ex(SFConnectionManager *cm,
|
||||||
cm->server_group_index = server_group_index;
|
cm->server_group_index = server_group_index;
|
||||||
cm->module_name = module_name;
|
cm->module_name = module_name;
|
||||||
cm->common_cfg = common_cfg;
|
cm->common_cfg = common_cfg;
|
||||||
cm->server_cfg = server_cfg;
|
|
||||||
cm->alive_detect.bg_thread_enabled = bg_thread_enabled;
|
cm->alive_detect.bg_thread_enabled = bg_thread_enabled;
|
||||||
cm->max_servers_per_group = 0;
|
cm->max_servers_per_group = 0;
|
||||||
cm->extra = NULL;
|
cm->extra = NULL;
|
||||||
cm->exclude_server_id = 0;
|
|
||||||
|
|
||||||
cm->ops.get_connection = get_connection;
|
cm->ops.get_connection = get_connection;
|
||||||
cm->ops.get_server_connection = get_server_connection;
|
cm->ops.get_server_connection = get_server_connection;
|
||||||
|
|
@ -752,8 +687,8 @@ static int do_get_group_servers(SFConnectionManager *cm,
|
||||||
sarray.alloc = MAX_GROUP_SERVER_COUNT;
|
sarray.alloc = MAX_GROUP_SERVER_COUNT;
|
||||||
sarray.count = 0;
|
sarray.count = 0;
|
||||||
sarray.servers = fixed_servers;
|
sarray.servers = fixed_servers;
|
||||||
if ((result=sf_proto_get_group_servers(conn, cm->module_name, cm->
|
if ((result=sf_proto_get_group_servers(conn, cm->common_cfg->
|
||||||
common_cfg->network_timeout, group->id, &sarray)) != 0)
|
network_timeout, group->id, &sarray)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -778,7 +713,6 @@ static int do_get_group_servers(SFConnectionManager *cm,
|
||||||
static int get_group_servers_by_active(SFConnectionManager *cm,
|
static int get_group_servers_by_active(SFConnectionManager *cm,
|
||||||
SFCMConnGroupEntry *group)
|
SFCMConnGroupEntry *group)
|
||||||
{
|
{
|
||||||
const bool shared = true;
|
|
||||||
SFCMServerPtrArray *alives;
|
SFCMServerPtrArray *alives;
|
||||||
SFCMServerEntry **server;
|
SFCMServerEntry **server;
|
||||||
SFCMServerEntry **end;
|
SFCMServerEntry **end;
|
||||||
|
|
@ -794,7 +728,7 @@ static int get_group_servers_by_active(SFConnectionManager *cm,
|
||||||
end = alives->servers + alives->count;
|
end = alives->servers + alives->count;
|
||||||
for (server=alives->servers; server<end; server++) {
|
for (server=alives->servers; server<end; server++) {
|
||||||
if ((conn=make_connection(cm, (*server)->addr_array,
|
if ((conn=make_connection(cm, (*server)->addr_array,
|
||||||
shared, &result)) == NULL)
|
&result)) == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
@ -812,7 +746,6 @@ static int get_group_servers_by_active(SFConnectionManager *cm,
|
||||||
static int get_group_servers_by_all(SFConnectionManager *cm,
|
static int get_group_servers_by_all(SFConnectionManager *cm,
|
||||||
SFCMConnGroupEntry *group)
|
SFCMConnGroupEntry *group)
|
||||||
{
|
{
|
||||||
const bool shared = true;
|
|
||||||
SFCMServerEntry *server;
|
SFCMServerEntry *server;
|
||||||
SFCMServerEntry *end;
|
SFCMServerEntry *end;
|
||||||
ConnectionInfo *conn;
|
ConnectionInfo *conn;
|
||||||
|
|
@ -825,12 +758,8 @@ static int get_group_servers_by_all(SFConnectionManager *cm,
|
||||||
|
|
||||||
end = group->all.servers + group->all.count;
|
end = group->all.servers + group->all.count;
|
||||||
for (server=group->all.servers; server<end; server++) {
|
for (server=group->all.servers; server<end; server++) {
|
||||||
if (server->id == cm->exclude_server_id) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((conn=make_connection(cm, server->addr_array,
|
if ((conn=make_connection(cm, server->addr_array,
|
||||||
shared, &result)) == NULL)
|
&result)) == NULL)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,17 +26,16 @@
|
||||||
struct sf_connection_manager;
|
struct sf_connection_manager;
|
||||||
|
|
||||||
typedef ConnectionInfo *(*sf_get_connection_func)(
|
typedef ConnectionInfo *(*sf_get_connection_func)(
|
||||||
struct sf_connection_manager *cm, const int group_index,
|
struct sf_connection_manager *cm,
|
||||||
const bool shared, int *err_no);
|
const int group_index, int *err_no);
|
||||||
|
|
||||||
typedef ConnectionInfo *(*sf_get_server_connection_func)(
|
typedef ConnectionInfo *(*sf_get_server_connection_func)(
|
||||||
struct sf_connection_manager *cm,
|
struct sf_connection_manager *cm,
|
||||||
FCServerInfo *server, const bool shared, int *err_no);
|
FCServerInfo *server, int *err_no);
|
||||||
|
|
||||||
typedef ConnectionInfo *(*sf_get_spec_connection_func)(
|
typedef ConnectionInfo *(*sf_get_spec_connection_func)(
|
||||||
struct sf_connection_manager *cm,
|
struct sf_connection_manager *cm,
|
||||||
const ConnectionInfo *target,
|
const ConnectionInfo *target, int *err_no);
|
||||||
const bool shared, int *err_no);
|
|
||||||
|
|
||||||
typedef void (*sf_release_connection_func)(
|
typedef void (*sf_release_connection_func)(
|
||||||
struct sf_connection_manager *cm, ConnectionInfo *conn);
|
struct sf_connection_manager *cm, ConnectionInfo *conn);
|
||||||
|
|
@ -104,9 +103,8 @@ typedef struct sf_cm_operations {
|
||||||
} SFCMOperations;
|
} SFCMOperations;
|
||||||
|
|
||||||
typedef struct sf_connection_manager {
|
typedef struct sf_connection_manager {
|
||||||
int exclude_server_id; //for server side
|
short server_group_index;
|
||||||
uint16_t max_servers_per_group;
|
short max_servers_per_group;
|
||||||
uint8_t server_group_index;
|
|
||||||
struct {
|
struct {
|
||||||
bool bg_thread_enabled;
|
bool bg_thread_enabled;
|
||||||
struct common_blocked_queue queue;
|
struct common_blocked_queue queue;
|
||||||
|
|
@ -117,7 +115,6 @@ typedef struct sf_connection_manager {
|
||||||
ConnectionPool cpool;
|
ConnectionPool cpool;
|
||||||
struct fast_mblock_man sptr_array_allocator; //element: SFCMServerPtrArray
|
struct fast_mblock_man sptr_array_allocator; //element: SFCMServerPtrArray
|
||||||
SFCMOperations ops;
|
SFCMOperations ops;
|
||||||
FCServerConfig *server_cfg;
|
|
||||||
void *extra; //for simple connection manager
|
void *extra; //for simple connection manager
|
||||||
} SFConnectionManager;
|
} SFConnectionManager;
|
||||||
|
|
||||||
|
|
@ -126,8 +123,7 @@ int sf_connection_manager_init_ex(SFConnectionManager *cm,
|
||||||
const int group_count, const int server_group_index,
|
const int group_count, const int server_group_index,
|
||||||
const int server_count, const int max_count_per_entry,
|
const int server_count, const int max_count_per_entry,
|
||||||
const int max_idle_time, fc_connection_callback_func
|
const int max_idle_time, fc_connection_callback_func
|
||||||
connect_done_callback, void *args, FCServerConfig *server_cfg,
|
connect_done_callback, void *args, const bool bg_thread_enabled);
|
||||||
const bool bg_thread_enabled);
|
|
||||||
|
|
||||||
static inline int sf_connection_manager_init(SFConnectionManager *cm,
|
static inline int sf_connection_manager_init(SFConnectionManager *cm,
|
||||||
const char *module_name, const SFClientCommonConfig *common_cfg,
|
const char *module_name, const SFClientCommonConfig *common_cfg,
|
||||||
|
|
@ -140,13 +136,7 @@ static inline int sf_connection_manager_init(SFConnectionManager *cm,
|
||||||
return sf_connection_manager_init_ex(cm, module_name,
|
return sf_connection_manager_init_ex(cm, module_name,
|
||||||
common_cfg, group_count, server_group_index,
|
common_cfg, group_count, server_group_index,
|
||||||
server_count, max_count_per_entry, max_idle_time,
|
server_count, max_count_per_entry, max_idle_time,
|
||||||
connect_done_callback, args, NULL, bg_thread_enabled);
|
connect_done_callback, args, bg_thread_enabled);
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_connection_manager_set_exclude_server_id(
|
|
||||||
SFConnectionManager *cm, const int exclude_server_id)
|
|
||||||
{
|
|
||||||
cm->exclude_server_id = exclude_server_id;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_connection_manager_add(SFConnectionManager *cm, const int group_id,
|
int sf_connection_manager_add(SFConnectionManager *cm, const int group_id,
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
#include "fastcommon/sockopt.h"
|
#include "fastcommon/sockopt.h"
|
||||||
|
|
||||||
#define SF_DEFAULT_CONNECT_TIMEOUT 10
|
#define SF_DEFAULT_CONNECT_TIMEOUT 2
|
||||||
#define SF_DEFAULT_NETWORK_TIMEOUT 60
|
#define SF_DEFAULT_NETWORK_TIMEOUT 10
|
||||||
|
|
||||||
#define SF_DEF_THREAD_STACK_SIZE (256 * 1024)
|
#define SF_DEF_THREAD_STACK_SIZE (256 * 1024)
|
||||||
#define SF_MIN_THREAD_STACK_SIZE (64 * 1024)
|
#define SF_MIN_THREAD_STACK_SIZE (64 * 1024)
|
||||||
|
|
@ -45,9 +45,8 @@
|
||||||
#define SF_NIO_TASK_STAGE_FETCH(task) task->nio_stages.current
|
#define SF_NIO_TASK_STAGE_FETCH(task) task->nio_stages.current
|
||||||
|
|
||||||
#define SF_SESSION_ERROR_NOT_EXIST 9992
|
#define SF_SESSION_ERROR_NOT_EXIST 9992
|
||||||
#define SF_CLUSTER_ERROR_NOT_LEADER 9995
|
#define SF_CLUSTER_ERROR_NOT_LEADER 9996
|
||||||
#define SF_CLUSTER_ERROR_LEADER_VERSION_INCONSISTENT 9996
|
#define SF_CLUSTER_ERROR_LEADER_VERSION_INCONSISTENT 9997
|
||||||
#define SF_CLUSTER_ERROR_BINLOG_MISSED 9997
|
|
||||||
#define SF_CLUSTER_ERROR_BINLOG_INCONSISTENT 9998
|
#define SF_CLUSTER_ERROR_BINLOG_INCONSISTENT 9998
|
||||||
#define SF_CLUSTER_ERROR_LEADER_INCONSISTENT 9999
|
#define SF_CLUSTER_ERROR_LEADER_INCONSISTENT 9999
|
||||||
#define SF_CLUSTER_ERROR_MASTER_INCONSISTENT SF_CLUSTER_ERROR_LEADER_INCONSISTENT
|
#define SF_CLUSTER_ERROR_MASTER_INCONSISTENT SF_CLUSTER_ERROR_LEADER_INCONSISTENT
|
||||||
|
|
@ -65,13 +64,9 @@
|
||||||
#define SF_ERROR_EBUSY 8816
|
#define SF_ERROR_EBUSY 8816
|
||||||
#define SF_ERROR_EINVAL 8822
|
#define SF_ERROR_EINVAL 8822
|
||||||
#define SF_ERROR_EAGAIN 8835
|
#define SF_ERROR_EAGAIN 8835
|
||||||
#define SF_ERROR_EINPROGRESS 8836
|
|
||||||
#define SF_ERROR_EOVERFLOW 8884
|
#define SF_ERROR_EOVERFLOW 8884
|
||||||
#define SF_ERROR_EOPNOTSUPP 8895
|
#define SF_ERROR_EOPNOTSUPP 8895
|
||||||
#define SF_ERROR_ENOLINK 8867
|
|
||||||
#define SF_ERROR_ENODATA 8861
|
#define SF_ERROR_ENODATA 8861
|
||||||
#define SF_ERROR_ENOTEMPTY 8839
|
|
||||||
#define SF_ERROR_ELOOP 8840
|
|
||||||
|
|
||||||
#define SF_FORCE_CLOSE_CONNECTION_ERROR_MIN SF_RETRIABLE_ERROR_NOT_MASTER
|
#define SF_FORCE_CLOSE_CONNECTION_ERROR_MIN SF_RETRIABLE_ERROR_NOT_MASTER
|
||||||
#define SF_FORCE_CLOSE_CONNECTION_ERROR_MAX SF_RETRIABLE_ERROR_MAX
|
#define SF_FORCE_CLOSE_CONNECTION_ERROR_MAX SF_RETRIABLE_ERROR_MAX
|
||||||
|
|
@ -96,8 +91,6 @@
|
||||||
#define SF_BINLOG_SOURCE_USER 'U' //by user call
|
#define SF_BINLOG_SOURCE_USER 'U' //by user call
|
||||||
#define SF_BINLOG_SOURCE_REPLAY 'R' //by binlog replay
|
#define SF_BINLOG_SOURCE_REPLAY 'R' //by binlog replay
|
||||||
|
|
||||||
#define SF_LOG_SCHEDULE_ENTRIES_COUNT 3
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -34,108 +34,45 @@
|
||||||
#include "sf_func.h"
|
#include "sf_func.h"
|
||||||
#include "sf_file_writer.h"
|
#include "sf_file_writer.h"
|
||||||
|
|
||||||
#define BINLOG_INDEX_ITEM_START_INDEX_STR "start_index"
|
#define BINLOG_INDEX_FILENAME SF_BINLOG_FILE_PREFIX"_index.dat"
|
||||||
#define BINLOG_INDEX_ITEM_START_INDEX_LEN \
|
|
||||||
(sizeof(BINLOG_INDEX_ITEM_START_INDEX_STR) - 1)
|
|
||||||
|
|
||||||
#define BINLOG_INDEX_ITEM_CURRENT_WRITE_STR "current_write"
|
#define BINLOG_INDEX_ITEM_CURRENT_WRITE "current_write"
|
||||||
#define BINLOG_INDEX_ITEM_CURRENT_WRITE_LEN \
|
#define BINLOG_INDEX_ITEM_CURRENT_COMPRESS "current_compress"
|
||||||
(sizeof(BINLOG_INDEX_ITEM_CURRENT_WRITE_STR) - 1)
|
|
||||||
|
|
||||||
#define BINLOG_INDEX_ITEM_CURRENT_COMPRESS_STR "current_compress"
|
#define GET_BINLOG_FILENAME(writer) \
|
||||||
#define BINLOG_INDEX_ITEM_CURRENT_COMPRESS_LEN \
|
sprintf(writer->file.name, "%s/%s/%s"SF_BINLOG_FILE_EXT_FMT, \
|
||||||
(sizeof(BINLOG_INDEX_ITEM_CURRENT_COMPRESS_STR) - 1)
|
writer->cfg.data_path, writer->cfg.subdir_name, \
|
||||||
|
SF_BINLOG_FILE_PREFIX, writer->binlog.index)
|
||||||
|
|
||||||
static inline void sf_file_writer_get_binlog_filename(SFFileWriterInfo *writer)
|
#define GET_BINLOG_INDEX_FILENAME_EX(data_path, subdir_name, filename, size) \
|
||||||
{
|
snprintf(filename, size, "%s/%s/%s", data_path, \
|
||||||
sf_file_writer_get_filename_ex(
|
subdir_name, BINLOG_INDEX_FILENAME)
|
||||||
writer->cfg.data_path, writer->cfg.subdir_name,
|
|
||||||
writer->cfg.file_prefix, writer->binlog.last_index,
|
|
||||||
writer->file.name.str, writer->file.name.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_file_writer_get_index_filename_ex(
|
#define GET_BINLOG_INDEX_FILENAME(writer, filename, size) \
|
||||||
const char *data_path, const char *subdir_name,
|
GET_BINLOG_INDEX_FILENAME_EX(writer->cfg.data_path, \
|
||||||
const char *file_prefix, const int file_prefix_len,
|
writer->cfg.subdir_name, filename, size)
|
||||||
char *filename, const int size)
|
|
||||||
{
|
|
||||||
#define INDEX_FILENAME_AFFIX_STR "_index.dat"
|
|
||||||
#define INDEX_FILENAME_AFFIX_LEN (sizeof(INDEX_FILENAME_AFFIX_STR) - 1)
|
|
||||||
|
|
||||||
char *p;
|
|
||||||
int data_path_len;
|
|
||||||
int subdir_name_len;
|
|
||||||
|
|
||||||
data_path_len = strlen(data_path);
|
|
||||||
subdir_name_len = strlen(subdir_name);
|
|
||||||
if (data_path_len + 1 + subdir_name_len + 1 + file_prefix_len +
|
|
||||||
INDEX_FILENAME_AFFIX_LEN >= size)
|
|
||||||
{
|
|
||||||
*filename = '\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(filename, data_path, data_path_len);
|
|
||||||
p = filename + data_path_len;
|
|
||||||
*p++ = '/';
|
|
||||||
|
|
||||||
memcpy(p, subdir_name, subdir_name_len);
|
|
||||||
p += subdir_name_len;
|
|
||||||
*p++ = '/';
|
|
||||||
|
|
||||||
memcpy(p, file_prefix, file_prefix_len);
|
|
||||||
p += file_prefix_len;
|
|
||||||
|
|
||||||
memcpy(p, INDEX_FILENAME_AFFIX_STR, INDEX_FILENAME_AFFIX_LEN);
|
|
||||||
p += INDEX_FILENAME_AFFIX_LEN;
|
|
||||||
*p = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
const char *sf_file_writer_get_index_filename(const char *data_path,
|
const char *sf_file_writer_get_index_filename(const char *data_path,
|
||||||
const char *subdir_name, char *filename, const int size)
|
const char *subdir_name, char *filename, const int size)
|
||||||
{
|
{
|
||||||
sf_file_writer_get_index_filename_ex(data_path, subdir_name,
|
GET_BINLOG_INDEX_FILENAME_EX(data_path, subdir_name, filename, size);
|
||||||
SF_BINLOG_FILE_PREFIX_STR, SF_BINLOG_FILE_PREFIX_LEN,
|
|
||||||
filename, size);
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_write_to_binlog_index_file_ex(const char *data_path,
|
static int write_to_binlog_index_file(SFFileWriterInfo *writer)
|
||||||
const char *subdir_name, const char *file_prefix,
|
|
||||||
const int start_index, const int last_index,
|
|
||||||
const int compress_index)
|
|
||||||
{
|
{
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
char buff[256];
|
char buff[256];
|
||||||
char *p;
|
|
||||||
int result;
|
int result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
sf_file_writer_get_index_filename_ex(data_path, subdir_name, file_prefix,
|
GET_BINLOG_INDEX_FILENAME(writer, filename, sizeof(filename));
|
||||||
strlen(file_prefix), filename, sizeof(filename));
|
len = sprintf(buff, "%s=%d\n"
|
||||||
p = buff;
|
"%s=%d\n",
|
||||||
memcpy(p, BINLOG_INDEX_ITEM_START_INDEX_STR,
|
BINLOG_INDEX_ITEM_CURRENT_WRITE,
|
||||||
BINLOG_INDEX_ITEM_START_INDEX_LEN);
|
writer->binlog.index,
|
||||||
p += BINLOG_INDEX_ITEM_START_INDEX_LEN;
|
BINLOG_INDEX_ITEM_CURRENT_COMPRESS,
|
||||||
*p++ = '=';
|
writer->binlog.compress_index);
|
||||||
p += fc_itoa(start_index, p);
|
|
||||||
*p++ = '\n';
|
|
||||||
|
|
||||||
memcpy(p, BINLOG_INDEX_ITEM_CURRENT_WRITE_STR,
|
|
||||||
BINLOG_INDEX_ITEM_CURRENT_WRITE_LEN);
|
|
||||||
p += BINLOG_INDEX_ITEM_CURRENT_WRITE_LEN;
|
|
||||||
*p++ = '=';
|
|
||||||
p += fc_itoa(last_index, p);
|
|
||||||
*p++ = '\n';
|
|
||||||
|
|
||||||
memcpy(p, BINLOG_INDEX_ITEM_CURRENT_COMPRESS_STR,
|
|
||||||
BINLOG_INDEX_ITEM_CURRENT_COMPRESS_LEN);
|
|
||||||
p += BINLOG_INDEX_ITEM_CURRENT_COMPRESS_LEN;
|
|
||||||
*p++ = '=';
|
|
||||||
p += fc_itoa(compress_index, p);
|
|
||||||
*p++ = '\n';
|
|
||||||
|
|
||||||
len = p - buff;
|
|
||||||
if ((result=safeWriteToFile(filename, buff, len)) != 0) {
|
if ((result=safeWriteToFile(filename, buff, len)) != 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"write to file \"%s\" fail, errno: %d, error info: %s",
|
"write to file \"%s\" fail, errno: %d, error info: %s",
|
||||||
|
|
@ -145,27 +82,20 @@ int sf_file_writer_write_to_binlog_index_file_ex(const char *data_path,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int write_to_binlog_index_file(SFFileWriterInfo *writer)
|
static int get_binlog_index_from_file(SFFileWriterInfo *writer)
|
||||||
{
|
|
||||||
return sf_file_writer_write_to_binlog_index_file_ex(
|
|
||||||
writer->cfg.data_path, writer->cfg.subdir_name,
|
|
||||||
writer->cfg.file_prefix, writer->binlog.start_index,
|
|
||||||
writer->binlog.last_index, writer->binlog.compress_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int get_binlog_info_from_file(const char *data_path,
|
|
||||||
const char *subdir_name, int *start_index,
|
|
||||||
int *last_index, int *compress_index)
|
|
||||||
{
|
{
|
||||||
char full_filename[PATH_MAX];
|
char full_filename[PATH_MAX];
|
||||||
IniContext ini_context;
|
IniContext ini_context;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
sf_file_writer_get_index_filename_ex(data_path, subdir_name,
|
snprintf(full_filename, sizeof(full_filename), "%s/%s/%s",
|
||||||
SF_BINLOG_FILE_PREFIX_STR, SF_BINLOG_FILE_PREFIX_LEN,
|
writer->cfg.data_path, writer->cfg.subdir_name,
|
||||||
full_filename, sizeof(full_filename));
|
BINLOG_INDEX_FILENAME);
|
||||||
if (access(full_filename, F_OK) != 0) {
|
if (access(full_filename, F_OK) != 0) {
|
||||||
return errno != 0 ? errno : EPERM;
|
if (errno == ENOENT) {
|
||||||
|
writer->binlog.index = 0;
|
||||||
|
return write_to_binlog_index_file(writer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=iniLoadFromFile(full_filename, &ini_context)) != 0) {
|
if ((result=iniLoadFromFile(full_filename, &ini_context)) != 0) {
|
||||||
|
|
@ -175,71 +105,29 @@ static int get_binlog_info_from_file(const char *data_path,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
*start_index = iniGetIntValue(NULL,
|
writer->binlog.index = iniGetIntValue(NULL,
|
||||||
BINLOG_INDEX_ITEM_START_INDEX_STR,
|
BINLOG_INDEX_ITEM_CURRENT_WRITE, &ini_context, 0);
|
||||||
&ini_context, 0);
|
writer->binlog.compress_index = iniGetIntValue(NULL,
|
||||||
*last_index = iniGetIntValue(NULL,
|
BINLOG_INDEX_ITEM_CURRENT_COMPRESS, &ini_context, 0);
|
||||||
BINLOG_INDEX_ITEM_CURRENT_WRITE_STR,
|
|
||||||
&ini_context, 0);
|
|
||||||
*compress_index = iniGetIntValue(NULL,
|
|
||||||
BINLOG_INDEX_ITEM_CURRENT_COMPRESS_STR,
|
|
||||||
&ini_context, 0);
|
|
||||||
|
|
||||||
iniFreeContext(&ini_context);
|
iniFreeContext(&ini_context);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_get_binlog_indexes(const char *data_path,
|
|
||||||
const char *subdir_name, int *start_index, int *last_index)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
int compress_index;
|
|
||||||
|
|
||||||
result = get_binlog_info_from_file(data_path, subdir_name,
|
|
||||||
start_index, last_index, &compress_index);
|
|
||||||
if (result == ENOENT) {
|
|
||||||
*start_index = *last_index = 0;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int get_binlog_index_from_file(SFFileWriterInfo *writer)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
result = get_binlog_info_from_file(writer->cfg.data_path,
|
|
||||||
writer->cfg.subdir_name, &writer->binlog.start_index,
|
|
||||||
&writer->binlog.last_index, &writer->binlog.compress_index);
|
|
||||||
if (result == ENOENT) {
|
|
||||||
writer->binlog.start_index = 0;
|
|
||||||
writer->binlog.last_index = 0;
|
|
||||||
writer->binlog.compress_index = 0;
|
|
||||||
if (writer->cfg.file_rotate_size > 0) {
|
|
||||||
return write_to_binlog_index_file(writer);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int open_writable_binlog(SFFileWriterInfo *writer)
|
static int open_writable_binlog(SFFileWriterInfo *writer)
|
||||||
{
|
{
|
||||||
if (writer->file.fd >= 0) {
|
if (writer->file.fd >= 0) {
|
||||||
close(writer->file.fd);
|
close(writer->file.fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
sf_file_writer_get_binlog_filename(writer);
|
GET_BINLOG_FILENAME(writer);
|
||||||
writer->file.fd = open(writer->file.name.str, O_WRONLY |
|
writer->file.fd = open(writer->file.name,
|
||||||
O_CREAT | O_APPEND | O_CLOEXEC, 0644);
|
O_WRONLY | O_CREAT | O_APPEND, 0644);
|
||||||
if (writer->file.fd < 0) {
|
if (writer->file.fd < 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"open file \"%s\" fail, "
|
"open file \"%s\" fail, "
|
||||||
"errno: %d, error info: %s",
|
"errno: %d, error info: %s",
|
||||||
__LINE__, writer->file.name.str,
|
__LINE__, writer->file.name,
|
||||||
errno, STRERROR(errno));
|
errno, STRERROR(errno));
|
||||||
return errno != 0 ? errno : EACCES;
|
return errno != 0 ? errno : EACCES;
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +137,7 @@ static int open_writable_binlog(SFFileWriterInfo *writer)
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"lseek file \"%s\" fail, "
|
"lseek file \"%s\" fail, "
|
||||||
"errno: %d, error info: %s",
|
"errno: %d, error info: %s",
|
||||||
__LINE__, writer->file.name.str,
|
__LINE__, writer->file.name,
|
||||||
errno, STRERROR(errno));
|
errno, STRERROR(errno));
|
||||||
return errno != 0 ? errno : EIO;
|
return errno != 0 ? errno : EIO;
|
||||||
}
|
}
|
||||||
|
|
@ -259,24 +147,23 @@ static int open_writable_binlog(SFFileWriterInfo *writer)
|
||||||
|
|
||||||
static int open_next_binlog(SFFileWriterInfo *writer)
|
static int open_next_binlog(SFFileWriterInfo *writer)
|
||||||
{
|
{
|
||||||
sf_file_writer_get_binlog_filename(writer);
|
GET_BINLOG_FILENAME(writer);
|
||||||
if (access(writer->file.name.str, F_OK) == 0) {
|
if (access(writer->file.name, F_OK) == 0) {
|
||||||
char bak_filename[PATH_MAX];
|
char bak_filename[PATH_MAX];
|
||||||
char date_str[32];
|
char date_str[32];
|
||||||
|
|
||||||
formatDatetime(g_current_time, "%Y%m%d%H%M%S",
|
snprintf(bak_filename, sizeof(bak_filename), "%s.%s",
|
||||||
date_str, sizeof(date_str));
|
writer->file.name, formatDatetime(g_current_time,
|
||||||
fc_combine_two_strings(writer->file.name.str,
|
"%Y%m%d%H%M%S", date_str, sizeof(date_str)));
|
||||||
date_str, '.', bak_filename);
|
if (rename(writer->file.name, bak_filename) == 0) {
|
||||||
if (rename(writer->file.name.str, bak_filename) == 0) {
|
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"binlog file %s exist, rename to %s",
|
"binlog file %s exist, rename to %s",
|
||||||
__LINE__, writer->file.name.str, bak_filename);
|
__LINE__, writer->file.name, bak_filename);
|
||||||
} else {
|
} else {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"rename binlog %s to backup %s fail, "
|
"rename binlog %s to backup %s fail, "
|
||||||
"errno: %d, error info: %s",
|
"errno: %d, error info: %s",
|
||||||
__LINE__, writer->file.name.str, bak_filename,
|
__LINE__, writer->file.name, bak_filename,
|
||||||
errno, STRERROR(errno));
|
errno, STRERROR(errno));
|
||||||
return errno != 0 ? errno : EPERM;
|
return errno != 0 ? errno : EPERM;
|
||||||
}
|
}
|
||||||
|
|
@ -295,43 +182,35 @@ static int do_write_to_file(SFFileWriterInfo *writer,
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"write to binlog file \"%s\" fail, "
|
"write to binlog file \"%s\" fail, "
|
||||||
"errno: %d, error info: %s",
|
"errno: %d, error info: %s",
|
||||||
__LINE__, writer->file.name.str,
|
__LINE__, writer->file.name,
|
||||||
result, STRERROR(result));
|
result, STRERROR(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writer->cfg.call_fsync) {
|
if (fsync(writer->file.fd) != 0) {
|
||||||
if (fsync(writer->file.fd) != 0) {
|
result = errno != 0 ? errno : EIO;
|
||||||
result = errno != 0 ? errno : EIO;
|
logError("file: "__FILE__", line: %d, "
|
||||||
logError("file: "__FILE__", line: %d, "
|
"fsync to binlog file \"%s\" fail, "
|
||||||
"fsync to binlog file \"%s\" fail, errno: %d, "
|
"errno: %d, error info: %s",
|
||||||
"error info: %s", __LINE__, writer->file.name.str,
|
__LINE__, writer->file.name,
|
||||||
result, STRERROR(result));
|
result, STRERROR(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
writer->file.size += len;
|
writer->file.size += len;
|
||||||
if (writer->write_done_callback.func != NULL) {
|
|
||||||
writer->write_done_callback.func(writer,
|
|
||||||
writer->write_done_callback.args);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_direct_write(SFFileWriterInfo *writer,
|
static int check_write_to_file(SFFileWriterInfo *writer,
|
||||||
char *buff, const int len)
|
char *buff, const int len)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((writer->cfg.file_rotate_size <= 0) || (writer->file.size
|
if (writer->file.size + len <= SF_BINLOG_FILE_MAX_SIZE) {
|
||||||
+ len <= writer->cfg.file_rotate_size))
|
|
||||||
{
|
|
||||||
return do_write_to_file(writer, buff, len);
|
return do_write_to_file(writer, buff, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer->binlog.last_index++; //binlog rotate
|
writer->binlog.index++; //binlog rotate
|
||||||
if ((result=write_to_binlog_index_file(writer)) == 0) {
|
if ((result=write_to_binlog_index_file(writer)) == 0) {
|
||||||
result = open_next_binlog(writer);
|
result = open_next_binlog(writer);
|
||||||
}
|
}
|
||||||
|
|
@ -339,7 +218,7 @@ int sf_file_writer_direct_write(SFFileWriterInfo *writer,
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"open binlog file \"%s\" fail",
|
"open binlog file \"%s\" fail",
|
||||||
__LINE__, writer->file.name.str);
|
__LINE__, writer->file.name);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,96 +230,58 @@ int sf_file_writer_flush(SFFileWriterInfo *writer)
|
||||||
int result;
|
int result;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
len = SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH(writer->binlog_buffer);
|
len = SF_BINLOG_BUFFER_LENGTH(writer->binlog_buffer);
|
||||||
if (len == 0) {
|
if (len == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=sf_file_writer_direct_write(writer, writer->
|
result = check_write_to_file(writer, writer->binlog_buffer.buff, len);
|
||||||
binlog_buffer.buff, len)) == 0)
|
writer->binlog_buffer.end = writer->binlog_buffer.buff;
|
||||||
{
|
|
||||||
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
|
||||||
writer->last_versions.done = writer->last_versions.pending;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writer->binlog_buffer.data_end = writer->binlog_buffer.buff;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_fsync(SFFileWriterInfo *writer)
|
int sf_file_writer_get_current_index(SFFileWriterInfo *writer)
|
||||||
{
|
{
|
||||||
int result;
|
|
||||||
|
|
||||||
if ((result=sf_file_writer_flush(writer)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fsync(writer->file.fd) == 0) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
result = errno != 0 ? errno : EIO;
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"fsync to binlog file \"%s\" fail, errno: %d, "
|
|
||||||
"error info: %s", __LINE__, writer->file.name.str,
|
|
||||||
result, STRERROR(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_get_indexes(SFFileWriterInfo *writer,
|
|
||||||
int *start_index, int *last_index)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (writer == NULL) { //for data recovery
|
if (writer == NULL) { //for data recovery
|
||||||
*start_index = *last_index = 0;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writer->binlog.last_index < 0) {
|
if (writer->binlog.index < 0) {
|
||||||
if ((result=get_binlog_index_from_file(writer)) != 0) {
|
get_binlog_index_from_file(writer);
|
||||||
*start_index = *last_index = -1;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*start_index = writer->binlog.start_index;
|
return writer->binlog.index;
|
||||||
*last_index = writer->binlog.last_index;
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_deal_versioned_buffer(SFFileWriterInfo *writer,
|
int sf_file_writer_deal_buffer(SFFileWriterInfo *writer,
|
||||||
BufferInfo *buffer, const int64_t version)
|
BufferInfo *buffer, const int64_t version)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (buffer->length >= writer->binlog_buffer.size / 4) {
|
if (buffer->length >= writer->binlog_buffer.size / 4) {
|
||||||
if (SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH(writer->binlog_buffer) > 0) {
|
if (SF_BINLOG_BUFFER_LENGTH(writer->binlog_buffer) > 0) {
|
||||||
if ((result=sf_file_writer_flush(writer)) != 0) {
|
if ((result=sf_file_writer_flush(writer)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=sf_file_writer_direct_write(writer, buffer->
|
if ((result=check_write_to_file(writer, buffer->buff,
|
||||||
buff, buffer->length)) == 0)
|
buffer->length)) == 0)
|
||||||
{
|
{
|
||||||
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
||||||
writer->last_versions.pending = version;
|
writer->last_versions.pending = version;
|
||||||
writer->last_versions.done = version;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (writer->cfg.file_rotate_size > 0 && writer->file.size +
|
if (writer->file.size + SF_BINLOG_BUFFER_LENGTH(writer->
|
||||||
SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH(writer->binlog_buffer) +
|
binlog_buffer) + buffer->length > SF_BINLOG_FILE_MAX_SIZE)
|
||||||
buffer->length > writer->cfg.file_rotate_size)
|
|
||||||
{
|
{
|
||||||
if ((result=sf_file_writer_flush(writer)) != 0) {
|
if ((result=sf_file_writer_flush(writer)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
} else if (SF_BINLOG_BUFFER_PRODUCER_BUFF_REMAIN(
|
} else if (writer->binlog_buffer.size - SF_BINLOG_BUFFER_LENGTH(
|
||||||
writer->binlog_buffer) < buffer->length)
|
writer->binlog_buffer) < buffer->length)
|
||||||
{
|
{
|
||||||
if ((result=sf_file_writer_flush(writer)) != 0) {
|
if ((result=sf_file_writer_flush(writer)) != 0) {
|
||||||
|
|
@ -451,40 +292,15 @@ int sf_file_writer_deal_versioned_buffer(SFFileWriterInfo *writer,
|
||||||
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
||||||
writer->last_versions.pending = version;
|
writer->last_versions.pending = version;
|
||||||
}
|
}
|
||||||
memcpy(writer->binlog_buffer.data_end, buffer->buff, buffer->length);
|
memcpy(writer->binlog_buffer.end, buffer->buff, buffer->length);
|
||||||
writer->binlog_buffer.data_end += buffer->length;
|
writer->binlog_buffer.end += buffer->length;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_save_buffer_ex(SFFileWriterInfo *writer,
|
int sf_file_writer_init_normal(SFFileWriterInfo *writer,
|
||||||
const int length, const bool flush)
|
const char *data_path, const char *subdir_name,
|
||||||
{
|
const int buffer_size)
|
||||||
int result;
|
|
||||||
|
|
||||||
if (writer->cfg.file_rotate_size > 0 && writer->file.size +
|
|
||||||
SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH(writer->binlog_buffer) +
|
|
||||||
length > writer->cfg.file_rotate_size)
|
|
||||||
{
|
|
||||||
if ((result=sf_file_writer_flush(writer)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
writer->binlog_buffer.data_end += length;
|
|
||||||
if (flush || SF_BINLOG_BUFFER_PRODUCER_BUFF_REMAIN(writer->
|
|
||||||
binlog_buffer) < writer->cfg.max_record_size)
|
|
||||||
{
|
|
||||||
return sf_file_writer_flush(writer);
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_init(SFFileWriterInfo *writer, const char *data_path,
|
|
||||||
const char *subdir_name, const char *file_prefix,
|
|
||||||
const int max_record_size, const int buffer_size,
|
|
||||||
const int64_t file_rotate_size, const bool call_fsync)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int path_len;
|
int path_len;
|
||||||
|
|
@ -495,18 +311,15 @@ int sf_file_writer_init(SFFileWriterInfo *writer, const char *data_path,
|
||||||
writer->last_versions.pending = 0;
|
writer->last_versions.pending = 0;
|
||||||
writer->last_versions.done = 0;
|
writer->last_versions.done = 0;
|
||||||
writer->flags = 0;
|
writer->flags = 0;
|
||||||
sf_file_writer_set_write_done_callback(writer, NULL, NULL);
|
|
||||||
if ((result=sf_binlog_buffer_init(&writer->
|
if ((result=sf_binlog_buffer_init(&writer->
|
||||||
binlog_buffer, buffer_size)) != 0)
|
binlog_buffer, buffer_size)) != 0)
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
writer->cfg.max_record_size = max_record_size;
|
|
||||||
writer->cfg.call_fsync = call_fsync;
|
|
||||||
writer->cfg.file_rotate_size = file_rotate_size;
|
|
||||||
writer->cfg.data_path = data_path;
|
writer->cfg.data_path = data_path;
|
||||||
path_len = fc_combine_full_filepath(data_path, subdir_name, filepath);
|
path_len = snprintf(filepath, sizeof(filepath),
|
||||||
|
"%s/%s", data_path, subdir_name);
|
||||||
if ((result=fc_check_mkdir_ex(filepath, 0775, &create)) != 0) {
|
if ((result=fc_check_mkdir_ex(filepath, 0775, &create)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -515,11 +328,11 @@ int sf_file_writer_init(SFFileWriterInfo *writer, const char *data_path,
|
||||||
}
|
}
|
||||||
|
|
||||||
writer->file.fd = -1;
|
writer->file.fd = -1;
|
||||||
fc_safe_strcpy(writer->cfg.subdir_name, subdir_name);
|
snprintf(writer->cfg.subdir_name,
|
||||||
fc_safe_strcpy(writer->cfg.file_prefix, file_prefix);
|
sizeof(writer->cfg.subdir_name),
|
||||||
writer->file.name.size = path_len + 32;
|
"%s", subdir_name);
|
||||||
writer->file.name.str = (char *)fc_malloc(writer->file.name.size);
|
writer->file.name = (char *)fc_malloc(path_len + 32);
|
||||||
if (writer->file.name.str == NULL) {
|
if (writer->file.name == NULL) {
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -534,59 +347,13 @@ int sf_file_writer_init(SFFileWriterInfo *writer, const char *data_path,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_file_writer_destroy(SFFileWriterInfo *writer)
|
int sf_file_writer_set_binlog_index(SFFileWriterInfo *writer,
|
||||||
{
|
const int binlog_index)
|
||||||
if (writer->file.fd >= 0) {
|
|
||||||
close(writer->file.fd);
|
|
||||||
writer->file.fd = -1;
|
|
||||||
}
|
|
||||||
if (writer->file.name.str != NULL) {
|
|
||||||
free(writer->file.name.str);
|
|
||||||
writer->file.name.str = NULL;
|
|
||||||
}
|
|
||||||
sf_binlog_buffer_destroy(&writer->binlog_buffer);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_set_indexes(SFFileWriterInfo *writer,
|
|
||||||
const int start_index, const int last_index)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (writer->binlog.start_index != start_index ||
|
if (writer->binlog.index != binlog_index) {
|
||||||
writer->binlog.last_index != last_index)
|
writer->binlog.index = binlog_index;
|
||||||
{
|
|
||||||
writer->binlog.start_index = start_index;
|
|
||||||
writer->binlog.last_index = last_index;
|
|
||||||
if ((result=write_to_binlog_index_file(writer)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_set_binlog_start_index(SFFileWriterInfo *writer,
|
|
||||||
const int start_index)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (writer->binlog.start_index != start_index) {
|
|
||||||
writer->binlog.start_index = start_index;
|
|
||||||
if ((result=write_to_binlog_index_file(writer)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_set_binlog_write_index(SFFileWriterInfo *writer,
|
|
||||||
const int last_index)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (writer->binlog.last_index != last_index) {
|
|
||||||
writer->binlog.last_index = last_index;
|
|
||||||
if ((result=write_to_binlog_index_file(writer)) != 0) {
|
if ((result=write_to_binlog_index_file(writer)) != 0) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -600,108 +367,40 @@ int sf_file_writer_get_last_lines(const char *data_path,
|
||||||
char *buff, const int buff_size, int *count, int *length)
|
char *buff, const int buff_size, int *count, int *length)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int target_count;
|
int remain_count;
|
||||||
int count1;
|
int current_count;
|
||||||
|
int current_index;
|
||||||
|
int i;
|
||||||
char filename[PATH_MAX];
|
char filename[PATH_MAX];
|
||||||
string_t lines;
|
string_t lines;
|
||||||
|
|
||||||
target_count = *count;
|
current_index = current_write_index;
|
||||||
sf_file_writer_get_filename(data_path, subdir_name,
|
*length = 0;
|
||||||
current_write_index, filename, sizeof(filename));
|
remain_count = *count;
|
||||||
if (access(filename, F_OK) == 0) {
|
for (i=0; i<2; i++) {
|
||||||
if ((result=fc_get_last_lines(filename, buff, buff_size,
|
current_count = remain_count;
|
||||||
&lines, count)) != 0)
|
|
||||||
{
|
|
||||||
if (result != ENOENT) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*count >= target_count || current_write_index == 0) {
|
|
||||||
memmove(buff, lines.str, lines.len);
|
|
||||||
*length = lines.len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = errno != 0 ? errno : EPERM;
|
|
||||||
if (result == ENOENT) {
|
|
||||||
*count = 0;
|
|
||||||
*length = 0;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"stat file %s fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, filename, result, STRERROR(result));
|
|
||||||
*count = 0;
|
|
||||||
*length = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sf_file_writer_get_filename(data_path, subdir_name,
|
|
||||||
current_write_index - 1, filename, sizeof(filename));
|
|
||||||
if (access(filename, F_OK) != 0) {
|
|
||||||
result = errno != 0 ? errno : EPERM;
|
|
||||||
if (result == ENOENT) {
|
|
||||||
memmove(buff, lines.str, lines.len);
|
|
||||||
*length = lines.len;
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"stat file %s fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, filename, result, STRERROR(result));
|
|
||||||
*count = 0;
|
|
||||||
*length = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count1 = target_count - *count;
|
|
||||||
if ((result=fc_get_last_lines(filename, buff,
|
|
||||||
buff_size, &lines, &count1)) != 0)
|
|
||||||
{
|
|
||||||
*count = 0;
|
|
||||||
*length = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
memmove(buff, lines.str, lines.len);
|
|
||||||
*length = lines.len;
|
|
||||||
if (*count == 0) {
|
|
||||||
*count = count1;
|
|
||||||
} else {
|
|
||||||
sf_file_writer_get_filename(data_path, subdir_name,
|
sf_file_writer_get_filename(data_path, subdir_name,
|
||||||
current_write_index, filename, sizeof(filename));
|
current_index, filename, sizeof(filename));
|
||||||
if ((result=fc_get_first_lines(filename, buff + (*length),
|
result = fc_get_last_lines(filename, buff + *length,
|
||||||
buff_size - (*length), &lines, count)) != 0)
|
buff_size - *length, &lines, ¤t_count);
|
||||||
{
|
if (result == 0) {
|
||||||
|
memmove(buff + *length, lines.str, lines.len);
|
||||||
|
*length += lines.len;
|
||||||
|
remain_count -= current_count;
|
||||||
|
if (remain_count == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (result != ENOENT) {
|
||||||
*count = 0;
|
*count = 0;
|
||||||
*length = 0;
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
if (current_index == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
*count += count1;
|
--current_index; //try previous binlog file
|
||||||
*length += lines.len;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*count -= remain_count;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_file_writer_get_last_line(const char *data_path,
|
|
||||||
const char *subdir_name, char *buff,
|
|
||||||
const int buff_size, int *length)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
int last_index;
|
|
||||||
int count = 1;
|
|
||||||
|
|
||||||
if ((result=sf_file_writer_get_binlog_last_index(data_path,
|
|
||||||
subdir_name, &last_index)) != 0)
|
|
||||||
{
|
|
||||||
*length = 0;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
return sf_file_writer_get_last_lines(data_path, subdir_name,
|
|
||||||
last_index, buff, buff_size, &count, length);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -23,43 +23,30 @@
|
||||||
|
|
||||||
#define SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION 1
|
#define SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION 1
|
||||||
|
|
||||||
#define SF_BINLOG_SUBDIR_NAME_SIZE 128
|
#define SF_BINLOG_SUBDIR_NAME_SIZE 128
|
||||||
#define SF_BINLOG_FILE_PREFIX_STR_SIZE 64
|
#define SF_BINLOG_FILE_MAX_SIZE (1024 * 1024 * 1024) //for binlog rotating by size
|
||||||
#define SF_BINLOG_DEFAULT_ROTATE_SIZE (1024 * 1024 * 1024)
|
#define SF_BINLOG_FILE_PREFIX "binlog"
|
||||||
#define SF_BINLOG_NEVER_ROTATE_FILE 0
|
#define SF_BINLOG_FILE_EXT_FMT ".%06d"
|
||||||
#define SF_BINLOG_FILE_PREFIX_STR "binlog"
|
|
||||||
#define SF_BINLOG_FILE_PREFIX_LEN (sizeof(SF_BINLOG_FILE_PREFIX_STR) - 1)
|
|
||||||
#define SF_BINLOG_FILE_EXT_LEN 6
|
|
||||||
#define SF_BINLOG_FILE_EXT_FMT ".%0"FC_MACRO_TOSTRING(SF_BINLOG_FILE_EXT_LEN)"d"
|
|
||||||
|
|
||||||
struct sf_file_writer_info;
|
#define SF_BINLOG_BUFFER_LENGTH(buffer) ((buffer).end - (buffer).buff)
|
||||||
|
#define SF_BINLOG_BUFFER_REMAIN(buffer) ((buffer).end - (buffer).current)
|
||||||
typedef void (*sf_file_write_done_callback)(
|
|
||||||
struct sf_file_writer_info *writer, void *args);
|
|
||||||
|
|
||||||
typedef struct sf_file_writer_info {
|
typedef struct sf_file_writer_info {
|
||||||
struct {
|
struct {
|
||||||
const char *data_path;
|
const char *data_path;
|
||||||
char subdir_name[SF_BINLOG_SUBDIR_NAME_SIZE];
|
char subdir_name[SF_BINLOG_SUBDIR_NAME_SIZE];
|
||||||
char file_prefix[SF_BINLOG_FILE_PREFIX_STR_SIZE];
|
|
||||||
int64_t file_rotate_size;
|
|
||||||
int max_record_size;
|
int max_record_size;
|
||||||
bool call_fsync;
|
|
||||||
} cfg;
|
} cfg;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int start_index; //for read only
|
int index;
|
||||||
int last_index; //for write
|
|
||||||
int compress_index;
|
int compress_index;
|
||||||
} binlog;
|
} binlog;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int fd;
|
int fd;
|
||||||
int64_t size; //file size
|
int64_t size;
|
||||||
struct {
|
char *name;
|
||||||
char *str;
|
|
||||||
int size;
|
|
||||||
} name;
|
|
||||||
} file;
|
} file;
|
||||||
|
|
||||||
int64_t total_count;
|
int64_t total_count;
|
||||||
|
|
@ -70,252 +57,76 @@ typedef struct sf_file_writer_info {
|
||||||
int64_t pending;
|
int64_t pending;
|
||||||
volatile int64_t done;
|
volatile int64_t done;
|
||||||
} last_versions;
|
} last_versions;
|
||||||
|
|
||||||
struct {
|
|
||||||
sf_file_write_done_callback func;
|
|
||||||
void *args;
|
|
||||||
} write_done_callback;
|
|
||||||
|
|
||||||
} SFFileWriterInfo;
|
} SFFileWriterInfo;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sf_file_writer_init(SFFileWriterInfo *writer, const char *data_path,
|
int sf_file_writer_init_normal(SFFileWriterInfo *writer,
|
||||||
const char *subdir_name, const char *file_prefix,
|
const char *data_path, const char *subdir_name,
|
||||||
const int max_record_size, const int buffer_size,
|
const int buffer_size);
|
||||||
const int64_t file_rotate_size, const bool call_fsync);
|
|
||||||
|
|
||||||
void sf_file_writer_destroy(SFFileWriterInfo *writer);
|
int sf_file_writer_deal_buffer(SFFileWriterInfo *writer,
|
||||||
|
|
||||||
int sf_file_writer_direct_write(SFFileWriterInfo *writer,
|
|
||||||
char *buff, const int len);
|
|
||||||
|
|
||||||
int sf_file_writer_deal_versioned_buffer(SFFileWriterInfo *writer,
|
|
||||||
BufferInfo *buffer, const int64_t version);
|
BufferInfo *buffer, const int64_t version);
|
||||||
|
|
||||||
#define sf_file_writer_deal_buffer(writer, buffer) \
|
|
||||||
sf_file_writer_deal_versioned_buffer(writer, buffer, 0)
|
|
||||||
|
|
||||||
int sf_file_writer_flush(SFFileWriterInfo *writer);
|
int sf_file_writer_flush(SFFileWriterInfo *writer);
|
||||||
|
|
||||||
int sf_file_writer_fsync(SFFileWriterInfo *writer);
|
|
||||||
|
|
||||||
#define SF_FILE_WRITER_DATA_END_BUFF(writer) (writer)->binlog_buffer.data_end
|
|
||||||
#define SF_FILE_WRITER_CURRENT_DATA_VERSION(writer) \
|
|
||||||
(writer)->last_versions.pending
|
|
||||||
#define SF_FILE_WRITER_NEXT_DATA_VERSION(writer) \
|
|
||||||
++((writer)->last_versions.pending)
|
|
||||||
|
|
||||||
int sf_file_writer_save_buffer_ex(SFFileWriterInfo *writer,
|
|
||||||
const int length, const bool flush);
|
|
||||||
|
|
||||||
static inline int sf_file_writer_save_buffer(
|
|
||||||
SFFileWriterInfo *writer, const int length)
|
|
||||||
{
|
|
||||||
const bool flush = false;
|
|
||||||
return sf_file_writer_save_buffer_ex(writer, length, flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_file_writer_flush_buffer(
|
|
||||||
SFFileWriterInfo *writer, const int length)
|
|
||||||
{
|
|
||||||
const bool flush = true;
|
|
||||||
return sf_file_writer_save_buffer_ex(writer, length, flush);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_file_writer_set_flags(
|
static inline void sf_file_writer_set_flags(
|
||||||
SFFileWriterInfo *writer, const short flags)
|
SFFileWriterInfo *writer, const short flags)
|
||||||
{
|
{
|
||||||
writer->flags = flags;
|
writer->flags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sf_file_writer_set_call_fsync(
|
static inline int64_t sf_file_writer_get_last_version(
|
||||||
SFFileWriterInfo *writer, const bool call_fsync)
|
SFFileWriterInfo *writer)
|
||||||
{
|
|
||||||
writer->cfg.call_fsync = call_fsync;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_file_writer_set_write_done_callback (
|
|
||||||
SFFileWriterInfo *writer, sf_file_write_done_callback callback,
|
|
||||||
void *args)
|
|
||||||
{
|
|
||||||
writer->write_done_callback.func = callback;
|
|
||||||
writer->write_done_callback.args = args;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int64_t sf_file_writer_get_last_version_ex(
|
|
||||||
SFFileWriterInfo *writer, const int log_level)
|
|
||||||
{
|
{
|
||||||
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
if (writer->flags & SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION) {
|
||||||
return writer->last_versions.done;
|
return writer->last_versions.done;
|
||||||
} else {
|
} else {
|
||||||
if (FC_LOG_BY_LEVEL(log_level)) {
|
logError("file: "__FILE__", line: %d, "
|
||||||
log_it_ex(&g_log_context, log_level, "file: %s, line: %d, "
|
"should set writer flags to %d!", __LINE__,
|
||||||
"writer: %s, should set writer flags to %d!",
|
SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION);
|
||||||
__FILE__, __LINE__, writer->cfg.subdir_name,
|
|
||||||
SF_FILE_WRITER_FLAGS_WANT_DONE_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_file_writer_get_last_version(writer) \
|
int sf_file_writer_get_current_index(SFFileWriterInfo *writer);
|
||||||
sf_file_writer_get_last_version_ex(writer, LOG_ERR)
|
|
||||||
|
|
||||||
#define sf_file_writer_get_last_version_silence(writer) \
|
|
||||||
sf_file_writer_get_last_version_ex(writer, LOG_NOTHING)
|
|
||||||
|
|
||||||
int sf_file_writer_get_binlog_indexes(const char *data_path,
|
|
||||||
const char *subdir_name, int *start_index, int *last_index);
|
|
||||||
|
|
||||||
static inline int sf_file_writer_get_binlog_start_index(
|
|
||||||
const char *data_path, const char *subdir_name,
|
|
||||||
int *start_index)
|
|
||||||
{
|
|
||||||
int last_index;
|
|
||||||
return sf_file_writer_get_binlog_indexes(data_path,
|
|
||||||
subdir_name, start_index, &last_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_file_writer_get_binlog_last_index(
|
|
||||||
const char *data_path, const char *subdir_name,
|
|
||||||
int *last_index)
|
|
||||||
{
|
|
||||||
int start_index;
|
|
||||||
return sf_file_writer_get_binlog_indexes(data_path,
|
|
||||||
subdir_name, &start_index, last_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_set_indexes(SFFileWriterInfo *writer,
|
|
||||||
const int start_index, const int last_index);
|
|
||||||
|
|
||||||
int sf_file_writer_get_indexes(SFFileWriterInfo *writer,
|
|
||||||
int *start_index, int *last_index);
|
|
||||||
|
|
||||||
static inline int sf_file_writer_get_start_index(SFFileWriterInfo *writer)
|
|
||||||
{
|
|
||||||
int start_index;
|
|
||||||
int last_index;
|
|
||||||
|
|
||||||
sf_file_writer_get_indexes(writer, &start_index, &last_index);
|
|
||||||
return start_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_file_writer_get_last_index(SFFileWriterInfo *writer)
|
|
||||||
{
|
|
||||||
int start_index;
|
|
||||||
int last_index;
|
|
||||||
|
|
||||||
sf_file_writer_get_indexes(writer, &start_index, &last_index);
|
|
||||||
return last_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define sf_file_writer_get_current_write_index(writer) \
|
|
||||||
sf_file_writer_get_last_index(writer)
|
|
||||||
|
|
||||||
static inline void sf_file_writer_get_current_position(
|
static inline void sf_file_writer_get_current_position(
|
||||||
SFFileWriterInfo *writer, SFBinlogFilePosition *position)
|
SFFileWriterInfo *writer, SFBinlogFilePosition *position)
|
||||||
{
|
{
|
||||||
position->index = writer->binlog.last_index;
|
position->index = writer->binlog.index;
|
||||||
position->offset = writer->file.size;
|
position->offset = writer->file.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline const char *sf_file_writer_get_filepath(
|
static inline const char *sf_file_writer_get_filepath(
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
char *filepath, const int size)
|
|
||||||
{
|
|
||||||
fc_get_full_filepath_ex(data_path, strlen(data_path),
|
|
||||||
subdir_name, strlen(subdir_name), filepath, size);
|
|
||||||
return filepath;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline const char *sf_file_writer_get_filename_ex(
|
|
||||||
const char *data_path, const char *subdir_name,
|
|
||||||
const char *file_prefix, const int binlog_index,
|
|
||||||
char *filename, const int size)
|
char *filename, const int size)
|
||||||
{
|
{
|
||||||
char *p;
|
snprintf(filename, size, "%s/%s", data_path, subdir_name);
|
||||||
int data_path_len;
|
|
||||||
int subdir_name_len;
|
|
||||||
int file_prefix_len;
|
|
||||||
|
|
||||||
data_path_len = strlen(data_path);
|
|
||||||
subdir_name_len = strlen(subdir_name);
|
|
||||||
file_prefix_len = strlen(file_prefix);
|
|
||||||
if (data_path_len + subdir_name_len + file_prefix_len +
|
|
||||||
4 + SF_BINLOG_FILE_EXT_LEN >= size)
|
|
||||||
{
|
|
||||||
snprintf(filename, size, "%s/%s/%s"SF_BINLOG_FILE_EXT_FMT,
|
|
||||||
data_path, subdir_name, file_prefix, binlog_index);
|
|
||||||
return filename;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = filename;
|
|
||||||
memcpy(p, data_path, data_path_len);
|
|
||||||
p += data_path_len;
|
|
||||||
*p++ = '/';
|
|
||||||
memcpy(p, subdir_name, subdir_name_len);
|
|
||||||
p += subdir_name_len;
|
|
||||||
*p++ = '/';
|
|
||||||
memcpy(p, file_prefix, file_prefix_len);
|
|
||||||
p += file_prefix_len;
|
|
||||||
*p++ = '.';
|
|
||||||
fc_ltostr_ex(binlog_index, p, SF_BINLOG_FILE_EXT_LEN);
|
|
||||||
|
|
||||||
return filename;
|
return filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_file_writer_get_filename(data_path, subdir_name, \
|
static inline const char *sf_file_writer_get_filename(
|
||||||
binlog_index, filename, size) \
|
const char *data_path, const char *subdir_name,
|
||||||
sf_file_writer_get_filename_ex(data_path, subdir_name, \
|
const int binlog_index, char *filename, const int size)
|
||||||
SF_BINLOG_FILE_PREFIX_STR, binlog_index, filename, size)
|
{
|
||||||
|
snprintf(filename, size, "%s/%s/%s"SF_BINLOG_FILE_EXT_FMT, data_path,
|
||||||
|
subdir_name, SF_BINLOG_FILE_PREFIX, binlog_index);
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
const char *sf_file_writer_get_index_filename(const char *data_path,
|
const char *sf_file_writer_get_index_filename(const char *data_path,
|
||||||
const char *subdir_name, char *filename, const int size);
|
const char *subdir_name, char *filename, const int size);
|
||||||
|
|
||||||
int sf_file_writer_set_binlog_start_index(SFFileWriterInfo *writer,
|
int sf_file_writer_set_binlog_index(SFFileWriterInfo *writer,
|
||||||
const int start_index);
|
const int binlog_index);
|
||||||
|
|
||||||
int sf_file_writer_set_binlog_write_index(SFFileWriterInfo *writer,
|
|
||||||
const int last_index);
|
|
||||||
|
|
||||||
static inline int sf_file_writer_rotate_file(SFFileWriterInfo *writer)
|
|
||||||
{
|
|
||||||
int last_index;
|
|
||||||
last_index = sf_file_writer_get_current_write_index(writer);
|
|
||||||
return sf_file_writer_set_binlog_write_index(writer, last_index + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_get_last_lines(const char *data_path,
|
int sf_file_writer_get_last_lines(const char *data_path,
|
||||||
const char *subdir_name, const int current_write_index,
|
const char *subdir_name, const int current_write_index,
|
||||||
char *buff, const int buff_size, int *count, int *length);
|
char *buff, const int buff_size, int *count, int *length);
|
||||||
|
|
||||||
static inline int sf_file_writer_get_last_line_ex(const char *data_path,
|
|
||||||
const char *subdir_name, const int current_write_index,
|
|
||||||
char *buff, const int buff_size, int *length)
|
|
||||||
{
|
|
||||||
int count = 1;
|
|
||||||
return sf_file_writer_get_last_lines(data_path, subdir_name,
|
|
||||||
current_write_index, buff, buff_size, &count, length);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_file_writer_get_last_line(const char *data_path,
|
|
||||||
const char *subdir_name, char *buff,
|
|
||||||
const int buff_size, int *length);
|
|
||||||
|
|
||||||
int sf_file_writer_write_to_binlog_index_file_ex(const char *data_path,
|
|
||||||
const char *subdir_name, const char *file_prefix,
|
|
||||||
const int start_index, const int last_index,
|
|
||||||
const int compress_index);
|
|
||||||
|
|
||||||
#define sf_file_writer_write_to_binlog_index_file(data_path, \
|
|
||||||
subdir_name, start_index, last_index) \
|
|
||||||
sf_file_writer_write_to_binlog_index_file_ex(data_path, subdir_name, \
|
|
||||||
SF_BINLOG_FILE_PREFIX_STR, start_index, last_index, 0)
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -38,17 +38,16 @@ int sf_connect_to_server(const char *ip_addr, const int port, int *sock)
|
||||||
if(*sock < 0) {
|
if(*sock < 0) {
|
||||||
return errno != 0 ? errno : ENOMEM;
|
return errno != 0 ? errno : ENOMEM;
|
||||||
}
|
}
|
||||||
tcpsetserveropt(*sock, g_sf_global_vars.net_buffer_cfg.network_timeout);
|
tcpsetserveropt(*sock, g_sf_global_vars.network_timeout);
|
||||||
|
|
||||||
if ((result=tcpsetnonblockopt(*sock)) != 0) {
|
if ((result=tcpsetnonblockopt(*sock)) != 0) {
|
||||||
close(*sock);
|
close(*sock);
|
||||||
*sock = -1;
|
*sock = -1;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
FC_SET_CLOEXEC(*sock);
|
|
||||||
|
|
||||||
if ((result=connectserverbyip_nb(*sock, ip_addr, port, g_sf_global_vars.
|
if ((result=connectserverbyip_nb(*sock, ip_addr, port,
|
||||||
net_buffer_cfg.connect_timeout)) != 0)
|
g_sf_global_vars.connect_timeout)) != 0)
|
||||||
{
|
{
|
||||||
close(*sock);
|
close(*sock);
|
||||||
*sock = -1;
|
*sock = -1;
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ static inline void sf_terminate_myself_ex(const char *file,
|
||||||
{
|
{
|
||||||
g_sf_global_vars.continue_flag = false;
|
g_sf_global_vars.continue_flag = false;
|
||||||
if (kill(getpid(), SIGQUIT) == 0) { //signal myself to quit
|
if (kill(getpid(), SIGQUIT) == 0) { //signal myself to quit
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logInfo("file: "__FILE__", line: %d, "
|
||||||
"kill myself from caller {file: %s, line: %d, func: %s}",
|
"kill myself from caller {file: %s, line: %d, func: %s}",
|
||||||
__LINE__, file, line, func);
|
__LINE__, file, line, func);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -56,8 +56,7 @@ static inline int sf_binlog_buffer_init(SFBinlogBuffer *buffer, const int size)
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->current = buffer->data_end = buffer->buff;
|
buffer->current = buffer->end = buffer->buff;
|
||||||
buffer->buff_end = buffer->buff + size;
|
|
||||||
buffer->size = size;
|
buffer->size = size;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -66,8 +65,7 @@ static inline void sf_binlog_buffer_destroy(SFBinlogBuffer *buffer)
|
||||||
{
|
{
|
||||||
if (buffer->buff != NULL) {
|
if (buffer->buff != NULL) {
|
||||||
free(buffer->buff);
|
free(buffer->buff);
|
||||||
buffer->current = buffer->buff = NULL;
|
buffer->current = buffer->end = buffer->buff = NULL;
|
||||||
buffer->data_end = buffer->buff_end = NULL;
|
|
||||||
buffer->size = 0;
|
buffer->size = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -78,11 +76,6 @@ static inline int sf_synchronize_ctx_init(SFSynchronizeContext *sctx)
|
||||||
return init_pthread_lock_cond_pair(&sctx->lcp);
|
return init_pthread_lock_cond_pair(&sctx->lcp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sf_synchronize_ctx_destroy(SFSynchronizeContext *sctx)
|
|
||||||
{
|
|
||||||
destroy_pthread_lock_cond_pair(&sctx->lcp);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_synchronize_counter_add(
|
static inline void sf_synchronize_counter_add(
|
||||||
SFSynchronizeContext *sctx, const int count)
|
SFSynchronizeContext *sctx, const int count)
|
||||||
{
|
{
|
||||||
|
|
@ -119,34 +112,6 @@ static inline void sf_synchronize_counter_wait(SFSynchronizeContext *sctx)
|
||||||
PTHREAD_MUTEX_UNLOCK(&sctx->lcp.lock);
|
PTHREAD_MUTEX_UNLOCK(&sctx->lcp.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_synchronize_finished_notify_no_lock(sctx, err_no) \
|
|
||||||
(sctx)->finished = true; \
|
|
||||||
(sctx)->result = err_no; \
|
|
||||||
pthread_cond_signal(&(sctx)->lcp.cond)
|
|
||||||
|
|
||||||
static inline void sf_synchronize_finished_notify(
|
|
||||||
SFSynchronizeContext *sctx, const int result)
|
|
||||||
{
|
|
||||||
PTHREAD_MUTEX_LOCK(&sctx->lcp.lock);
|
|
||||||
sf_synchronize_finished_notify_no_lock(sctx, result);
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&sctx->lcp.lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_synchronize_finished_wait(SFSynchronizeContext *sctx)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
PTHREAD_MUTEX_LOCK(&sctx->lcp.lock);
|
|
||||||
while (!sctx->finished && SF_G_CONTINUE_FLAG) {
|
|
||||||
pthread_cond_wait(&sctx->lcp.cond, &sctx->lcp.lock);
|
|
||||||
}
|
|
||||||
result = sctx->result;
|
|
||||||
sctx->finished = false; //for next notify
|
|
||||||
PTHREAD_MUTEX_UNLOCK(&sctx->lcp.lock);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
894
src/sf_global.c
894
src/sf_global.c
File diff suppressed because it is too large
Load Diff
204
src/sf_global.h
204
src/sf_global.h
|
|
@ -30,36 +30,32 @@ typedef struct sf_connection_stat {
|
||||||
} SFConnectionStat;
|
} SFConnectionStat;
|
||||||
|
|
||||||
typedef struct sf_global_variables {
|
typedef struct sf_global_variables {
|
||||||
|
int connect_timeout;
|
||||||
|
int network_timeout;
|
||||||
struct {
|
struct {
|
||||||
char str[MAX_PATH_SIZE];
|
char str[MAX_PATH_SIZE];
|
||||||
int len;
|
|
||||||
bool inited;
|
bool inited;
|
||||||
bool created;
|
|
||||||
} base_path;
|
} base_path;
|
||||||
|
|
||||||
volatile bool continue_flag;
|
volatile bool continue_flag;
|
||||||
bool tcp_quick_ack;
|
bool tcp_quick_ack;
|
||||||
bool epoll_edge_trigger;
|
int max_connections;
|
||||||
|
int max_pkg_size;
|
||||||
SFNetBufferConfig net_buffer_cfg;
|
int min_buff_size;
|
||||||
|
int max_buff_size;
|
||||||
int task_buffer_extra_size;
|
int task_buffer_extra_size;
|
||||||
int thread_stack_size;
|
int thread_stack_size;
|
||||||
|
|
||||||
time_t up_time;
|
time_t up_time;
|
||||||
struct {
|
gid_t run_by_gid;
|
||||||
bool inited;
|
uid_t run_by_uid;
|
||||||
gid_t gid;
|
char run_by_group[32];
|
||||||
uid_t uid;
|
char run_by_user[32];
|
||||||
char group[32];
|
|
||||||
char user[32];
|
|
||||||
} run_by;
|
|
||||||
|
|
||||||
SFLogConfig error_log;
|
SFLogConfig error_log;
|
||||||
SFConnectionStat connection_stat;
|
SFConnectionStat connection_stat;
|
||||||
sf_error_handler_callback error_handler;
|
sf_error_handler_callback error_handler;
|
||||||
string_t empty;
|
string_t empty;
|
||||||
volatile time_t last_binlog_writer_log_timestamp;
|
|
||||||
} SFGlobalVariables;
|
} SFGlobalVariables;
|
||||||
|
|
||||||
typedef struct sf_context_ini_config {
|
typedef struct sf_context_ini_config {
|
||||||
|
|
@ -67,9 +63,6 @@ typedef struct sf_context_ini_config {
|
||||||
int default_inner_port;
|
int default_inner_port;
|
||||||
int default_outer_port;
|
int default_outer_port;
|
||||||
int default_work_threads;
|
int default_work_threads;
|
||||||
int max_pkg_size_min_value;
|
|
||||||
FCCommunicationType comm_type;
|
|
||||||
const char *max_pkg_size_item_name;
|
|
||||||
} SFContextIniConfig;
|
} SFContextIniConfig;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
@ -80,36 +73,13 @@ extern SFGlobalVariables g_sf_global_vars;
|
||||||
extern SFContext g_sf_context;
|
extern SFContext g_sf_context;
|
||||||
|
|
||||||
#define SF_G_BASE_PATH_STR g_sf_global_vars.base_path.str
|
#define SF_G_BASE_PATH_STR g_sf_global_vars.base_path.str
|
||||||
#define SF_G_BASE_PATH_LEN g_sf_global_vars.base_path.len
|
|
||||||
#define SF_G_BASE_PATH_INITED g_sf_global_vars.base_path.inited
|
#define SF_G_BASE_PATH_INITED g_sf_global_vars.base_path.inited
|
||||||
#define SF_G_BASE_PATH_CREATED g_sf_global_vars.base_path.created
|
|
||||||
#define SF_G_CONTINUE_FLAG g_sf_global_vars.continue_flag
|
#define SF_G_CONTINUE_FLAG g_sf_global_vars.continue_flag
|
||||||
#define SF_G_CONNECT_TIMEOUT g_sf_global_vars.net_buffer_cfg.connect_timeout
|
#define SF_G_CONNECT_TIMEOUT g_sf_global_vars.connect_timeout
|
||||||
#define SF_G_NETWORK_TIMEOUT g_sf_global_vars.net_buffer_cfg.network_timeout
|
#define SF_G_NETWORK_TIMEOUT g_sf_global_vars.network_timeout
|
||||||
#define SF_G_MAX_CONNECTIONS g_sf_global_vars.net_buffer_cfg.max_connections
|
#define SF_G_MAX_CONNECTIONS g_sf_global_vars.max_connections
|
||||||
#define SF_G_THREAD_STACK_SIZE g_sf_global_vars.thread_stack_size
|
#define SF_G_THREAD_STACK_SIZE g_sf_global_vars.thread_stack_size
|
||||||
#define SF_G_UP_TIME g_sf_global_vars.up_time
|
|
||||||
|
|
||||||
#define SF_G_SOCK_HANDLER (g_sf_context.handlers \
|
|
||||||
[SF_IPV4_ADDRESS_FAMILY_INDEX].handlers + \
|
|
||||||
SF_SOCKET_NETWORK_HANDLER_INDEX)
|
|
||||||
#define SF_G_OUTER_PORT SF_G_SOCK_HANDLER->outer.port
|
|
||||||
#define SF_G_INNER_PORT SF_G_SOCK_HANDLER->inner.port
|
|
||||||
#define SF_G_OUTER_BIND_ADDR4 g_sf_context.handlers \
|
|
||||||
[SF_IPV4_ADDRESS_FAMILY_INDEX].outer_bind_addr
|
|
||||||
#define SF_G_INNER_BIND_ADDR4 g_sf_context.handlers \
|
|
||||||
[SF_IPV4_ADDRESS_FAMILY_INDEX].inner_bind_addr
|
|
||||||
#define SF_G_OUTER_BIND_ADDR6 g_sf_context.handlers \
|
|
||||||
[SF_IPV6_ADDRESS_FAMILY_INDEX].outer_bind_addr
|
|
||||||
#define SF_G_INNER_BIND_ADDR6 g_sf_context.handlers \
|
|
||||||
[SF_IPV6_ADDRESS_FAMILY_INDEX].inner_bind_addr
|
|
||||||
|
|
||||||
#define SF_G_IPV4_ENABLED (g_sf_context.handlers \
|
|
||||||
[SF_IPV4_ADDRESS_FAMILY_INDEX].af == AF_INET)
|
|
||||||
#define SF_G_IPV6_ENABLED (g_sf_context.handlers \
|
|
||||||
[SF_IPV6_ADDRESS_FAMILY_INDEX].af == AF_INET6)
|
|
||||||
|
|
||||||
#define SF_G_ACCEPT_THREADS g_sf_context.accept_threads
|
|
||||||
#define SF_G_WORK_THREADS g_sf_context.work_threads
|
#define SF_G_WORK_THREADS g_sf_context.work_threads
|
||||||
#define SF_G_ALIVE_THREAD_COUNT g_sf_context.thread_count
|
#define SF_G_ALIVE_THREAD_COUNT g_sf_context.thread_count
|
||||||
#define SF_G_THREAD_INDEX(tdata) (int)(tdata - g_sf_context.thread_data)
|
#define SF_G_THREAD_INDEX(tdata) (int)(tdata - g_sf_context.thread_data)
|
||||||
|
|
@ -118,150 +88,87 @@ extern SFContext g_sf_context;
|
||||||
|
|
||||||
#define SF_G_ERROR_HANDLER g_sf_global_vars.error_handler
|
#define SF_G_ERROR_HANDLER g_sf_global_vars.error_handler
|
||||||
#define SF_G_EMPTY_STRING g_sf_global_vars.empty
|
#define SF_G_EMPTY_STRING g_sf_global_vars.empty
|
||||||
#define LAST_BINLOG_WRITER_LOG_TIMESTAMP g_sf_global_vars. \
|
|
||||||
last_binlog_writer_log_timestamp
|
|
||||||
|
|
||||||
#define SF_G_EPOLL_EDGE_TRIGGER g_sf_global_vars.epoll_edge_trigger
|
#define SF_WORK_THREADS(sf_context) sf_context.work_threads
|
||||||
|
#define SF_ALIVE_THREAD_COUNT(sf_context) sf_context.thread_count
|
||||||
#define SF_WORK_THREADS(sf_context) (sf_context).work_threads
|
#define SF_THREAD_INDEX(sf_context, tdata) (int)(tdata - sf_context.thread_data)
|
||||||
#define SF_ALIVE_THREAD_COUNT(sf_context) (sf_context).thread_count
|
|
||||||
#define SF_THREAD_INDEX(sf_context, tdata) (int)(tdata - (sf_context).thread_data)
|
|
||||||
|
|
||||||
#define SF_IPV4_ENABLED(sf_context) ((sf_context).handlers \
|
|
||||||
[SF_IPV4_ADDRESS_FAMILY_INDEX].af == AF_INET)
|
|
||||||
#define SF_IPV6_ENABLED(sf_context) ((sf_context).handlers \
|
|
||||||
[SF_IPV6_ADDRESS_FAMILY_INDEX].af == AF_INET6)
|
|
||||||
|
|
||||||
#define SF_CHOWN_RETURN_ON_ERROR(path, current_uid, current_gid) \
|
#define SF_CHOWN_RETURN_ON_ERROR(path, current_uid, current_gid) \
|
||||||
do { \
|
do { \
|
||||||
if (g_sf_global_vars.run_by.inited && !(g_sf_global_vars. \
|
if (!(g_sf_global_vars.run_by_gid == current_gid && \
|
||||||
run_by.gid == current_gid && g_sf_global_vars. \
|
g_sf_global_vars.run_by_uid == current_uid)) \
|
||||||
run_by.uid == current_uid)) \
|
{ \
|
||||||
|
if (chown(path, g_sf_global_vars.run_by_uid, \
|
||||||
|
g_sf_global_vars.run_by_gid) != 0) \
|
||||||
{ \
|
{ \
|
||||||
if (chown(path, g_sf_global_vars.run_by.uid, \
|
logError("file: "__FILE__", line: %d, " \
|
||||||
g_sf_global_vars.run_by.gid) != 0) \
|
"chown \"%s\" fail, " \
|
||||||
{ \
|
"errno: %d, error info: %s", \
|
||||||
logError("file: "__FILE__", line: %d, " \
|
__LINE__, path, errno, STRERROR(errno)); \
|
||||||
"chown \"%s\" fail, " \
|
return errno != 0 ? errno : EPERM; \
|
||||||
"errno: %d, error info: %s", \
|
|
||||||
__LINE__, path, errno, STRERROR(errno)); \
|
|
||||||
return errno != 0 ? errno : EPERM; \
|
|
||||||
} \
|
|
||||||
} \
|
} \
|
||||||
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SF_CHOWN_TO_RUNBY_RETURN_ON_ERROR(path) \
|
#define SF_CHOWN_TO_RUNBY_RETURN_ON_ERROR(path) \
|
||||||
SF_CHOWN_RETURN_ON_ERROR(path, geteuid(), getegid())
|
SF_CHOWN_RETURN_ON_ERROR(path, geteuid(), getegid())
|
||||||
|
|
||||||
|
#define SF_SET_CONTEXT_INI_CONFIG(config, filename, pIniContext, \
|
||||||
#define SF_FCHOWN_RETURN_ON_ERROR(fd, path, current_uid, current_gid) \
|
section_name, def_inner_port, def_outer_port, def_work_threads) \
|
||||||
do { \
|
|
||||||
if (g_sf_global_vars.run_by.inited && !(g_sf_global_vars. \
|
|
||||||
run_by.gid == current_gid && g_sf_global_vars. \
|
|
||||||
run_by.uid == current_uid)) \
|
|
||||||
{ \
|
|
||||||
if (fchown(fd, g_sf_global_vars.run_by.uid, \
|
|
||||||
g_sf_global_vars.run_by.gid) != 0) \
|
|
||||||
{ \
|
|
||||||
logError("file: "__FILE__", line: %d, " \
|
|
||||||
"fchown \"%s\" fail, " \
|
|
||||||
"errno: %d, error info: %s", \
|
|
||||||
__LINE__, path, errno, STRERROR(errno)); \
|
|
||||||
return errno != 0 ? errno : EPERM; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define SF_FCHOWN_TO_RUNBY_RETURN_ON_ERROR(fd, path) \
|
|
||||||
SF_FCHOWN_RETURN_ON_ERROR(fd, path, geteuid(), getegid())
|
|
||||||
|
|
||||||
#define SF_SET_CONTEXT_INI_CONFIG_EX(config, the_comm_type, filename, \
|
|
||||||
pIniContext, section_name, def_inner_port, def_outer_port, \
|
|
||||||
def_work_threads, max_pkg_size_item_nm, max_pkg_size_min_val) \
|
|
||||||
do { \
|
do { \
|
||||||
FAST_INI_SET_FULL_CTX_EX(config.ini_ctx, filename, \
|
FAST_INI_SET_FULL_CTX_EX(config.ini_ctx, filename, \
|
||||||
section_name, pIniContext); \
|
section_name, pIniContext); \
|
||||||
config.comm_type = the_comm_type; \
|
|
||||||
config.default_inner_port = def_inner_port; \
|
config.default_inner_port = def_inner_port; \
|
||||||
config.default_outer_port = def_outer_port; \
|
config.default_outer_port = def_outer_port; \
|
||||||
config.default_work_threads = def_work_threads; \
|
config.default_work_threads = def_work_threads; \
|
||||||
config.max_pkg_size_item_name = max_pkg_size_item_nm; \
|
|
||||||
config.max_pkg_size_min_value = max_pkg_size_min_val; \
|
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SF_SET_CONTEXT_INI_CONFIG(config, the_comm_type, \
|
int sf_load_global_config_ex(const char *server_name,
|
||||||
filename, pIniContext, section_name, def_inner_port, \
|
|
||||||
def_outer_port, def_work_threads) \
|
|
||||||
SF_SET_CONTEXT_INI_CONFIG_EX(config, the_comm_type, filename, \
|
|
||||||
pIniContext, section_name, def_inner_port, def_outer_port, \
|
|
||||||
def_work_threads, "max_pkg_size", 0)
|
|
||||||
|
|
||||||
int sf_load_global_config_ex(const char *log_filename_prefix,
|
|
||||||
IniFullContext *ini_ctx, const bool load_network_params,
|
IniFullContext *ini_ctx, const bool load_network_params,
|
||||||
const char *max_pkg_size_item_nm, const int fixed_buff_size,
|
const int task_buffer_extra_size);
|
||||||
const int task_buffer_extra_size, const bool need_set_run_by);
|
|
||||||
|
|
||||||
static inline int sf_load_global_config(const char *log_filename_prefix,
|
static inline int sf_load_global_config(const char *server_name,
|
||||||
IniFullContext *ini_ctx)
|
IniFullContext *ini_ctx)
|
||||||
{
|
{
|
||||||
const bool load_network_params = true;
|
const bool load_network_params = true;
|
||||||
const char *max_pkg_size_item_nm = "max_pkg_size";
|
|
||||||
const int fixed_buff_size = 0;
|
|
||||||
const int task_buffer_extra_size = 0;
|
const int task_buffer_extra_size = 0;
|
||||||
const bool need_set_run_by = true;
|
|
||||||
|
|
||||||
return sf_load_global_config_ex(log_filename_prefix, ini_ctx,
|
return sf_load_global_config_ex(server_name, ini_ctx,
|
||||||
load_network_params, max_pkg_size_item_nm, fixed_buff_size,
|
load_network_params, task_buffer_extra_size);
|
||||||
task_buffer_extra_size, need_set_run_by);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_config_ex(const char *log_filename_prefix,
|
int sf_load_config_ex(const char *server_name,
|
||||||
SFContextIniConfig *config, const int fixed_buff_size,
|
SFContextIniConfig *config, const int task_buffer_extra_size);
|
||||||
const int task_buffer_extra_size, const bool need_set_run_by);
|
|
||||||
|
|
||||||
static inline int sf_load_config(const char *log_filename_prefix,
|
static inline int sf_load_config(const char *server_name,
|
||||||
const FCCommunicationType comm_type,
|
|
||||||
const char *filename, IniContext *pIniContext,
|
const char *filename, IniContext *pIniContext,
|
||||||
const char *section_name, const int default_inner_port,
|
const char *section_name, const int default_inner_port,
|
||||||
const int default_outer_port, const int fixed_buff_size,
|
const int default_outer_port, const int task_buffer_extra_size)
|
||||||
const int task_buffer_extra_size)
|
|
||||||
{
|
{
|
||||||
const bool need_set_run_by = true;
|
|
||||||
SFContextIniConfig config;
|
SFContextIniConfig config;
|
||||||
|
|
||||||
SF_SET_CONTEXT_INI_CONFIG(config, comm_type, filename, pIniContext,
|
SF_SET_CONTEXT_INI_CONFIG(config, filename, pIniContext,
|
||||||
section_name, default_inner_port, default_outer_port,
|
section_name, default_inner_port, default_outer_port,
|
||||||
DEFAULT_WORK_THREADS);
|
DEFAULT_WORK_THREADS);
|
||||||
return sf_load_config_ex(log_filename_prefix, &config, fixed_buff_size,
|
return sf_load_config_ex(server_name, &config, task_buffer_extra_size);
|
||||||
task_buffer_extra_size, need_set_run_by);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_load_context_from_config_ex(SFContext *sf_context,
|
int sf_load_context_from_config_ex(SFContext *sf_context,
|
||||||
SFContextIniConfig *config, const int fixed_buff_size,
|
SFContextIniConfig *config);
|
||||||
const int task_buffer_extra_size);
|
|
||||||
|
|
||||||
static inline int sf_load_context_from_config(SFContext *sf_context,
|
static inline int sf_load_context_from_config(SFContext *sf_context,
|
||||||
const FCCommunicationType comm_type,
|
|
||||||
const char *filename, IniContext *pIniContext,
|
const char *filename, IniContext *pIniContext,
|
||||||
const char *section_name, const int default_inner_port,
|
const char *section_name, const int default_inner_port,
|
||||||
const int default_outer_port, const int fixed_buff_size,
|
const int default_outer_port)
|
||||||
const int task_buffer_extra_size)
|
|
||||||
{
|
{
|
||||||
SFContextIniConfig config;
|
SFContextIniConfig config;
|
||||||
|
|
||||||
SF_SET_CONTEXT_INI_CONFIG(config, comm_type, filename, pIniContext,
|
SF_SET_CONTEXT_INI_CONFIG(config, filename, pIniContext,
|
||||||
section_name, default_inner_port, default_outer_port,
|
section_name, default_inner_port, default_outer_port,
|
||||||
DEFAULT_WORK_THREADS);
|
DEFAULT_WORK_THREADS);
|
||||||
return sf_load_context_from_config_ex(sf_context, &config,
|
return sf_load_context_from_config_ex(sf_context, &config);
|
||||||
fixed_buff_size, task_buffer_extra_size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_alloc_rdma_pd(SFContext *sf_context,
|
|
||||||
FCAddressPtrArray *address_array);
|
|
||||||
|
|
||||||
void sf_set_address_family_by_ip(SFContext *sf_context,
|
|
||||||
FCAddressPtrArray *address_array);
|
|
||||||
|
|
||||||
int sf_load_log_config(IniFullContext *ini_ctx, LogContext *log_ctx,
|
int sf_load_log_config(IniFullContext *ini_ctx, LogContext *log_ctx,
|
||||||
SFLogConfig *log_cfg);
|
SFLogConfig *log_cfg);
|
||||||
|
|
||||||
|
|
@ -286,14 +193,7 @@ void sf_log_config_to_string_ex(SFLogConfig *log_cfg, const char *caption,
|
||||||
void sf_slow_log_config_to_string(SFSlowLogConfig *slow_log_cfg,
|
void sf_slow_log_config_to_string(SFSlowLogConfig *slow_log_cfg,
|
||||||
const char *caption, char *output, const int size);
|
const char *caption, char *output, const int size);
|
||||||
|
|
||||||
void sf_global_config_to_string_ex(const char *max_pkg_size_item_nm,
|
void sf_global_config_to_string(char *output, const int size);
|
||||||
char *output, const int size);
|
|
||||||
|
|
||||||
static inline void sf_global_config_to_string(char *output, const int size)
|
|
||||||
{
|
|
||||||
const char *max_pkg_size_item_nm = "max_pkg_size";
|
|
||||||
sf_global_config_to_string_ex(max_pkg_size_item_nm, output, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_context_config_to_string(const SFContext *sf_context,
|
void sf_context_config_to_string(const SFContext *sf_context,
|
||||||
char *output, const int size);
|
char *output, const int size);
|
||||||
|
|
@ -305,22 +205,12 @@ void sf_log_config_ex(const char *other_config);
|
||||||
#define sf_log_config_to_string(log_cfg, caption, output, size) \
|
#define sf_log_config_to_string(log_cfg, caption, output, size) \
|
||||||
sf_log_config_to_string_ex(log_cfg, caption, NULL, output, size)
|
sf_log_config_to_string_ex(log_cfg, caption, NULL, output, size)
|
||||||
|
|
||||||
int sf_get_base_path_from_conf_file(const char *config_filename);
|
|
||||||
int sf_load_global_base_path(IniFullContext *ini_ctx);
|
int sf_load_global_base_path(IniFullContext *ini_ctx);
|
||||||
|
|
||||||
int sf_load_data_path_config_ex(IniFullContext *ini_ctx,
|
|
||||||
const char *item_name, const char *default_value, string_t *path);
|
|
||||||
|
|
||||||
#define sf_load_data_path_config(ini_ctx, path) \
|
|
||||||
sf_load_data_path_config_ex(ini_ctx, "data_path", "data", path)
|
|
||||||
|
|
||||||
static inline void sf_set_global_base_path(const char *base_path)
|
static inline void sf_set_global_base_path(const char *base_path)
|
||||||
{
|
{
|
||||||
string_t path_string;
|
snprintf(SF_G_BASE_PATH_STR, sizeof(SF_G_BASE_PATH_STR),
|
||||||
|
"%s", base_path);
|
||||||
FC_SET_STRING(path_string, (char *)base_path);
|
|
||||||
SF_G_BASE_PATH_LEN = normalize_path(NULL, &path_string,
|
|
||||||
SF_G_BASE_PATH_STR, sizeof(SF_G_BASE_PATH_STR));
|
|
||||||
SF_G_BASE_PATH_INITED = true;
|
SF_G_BASE_PATH_INITED = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
1504
src/sf_nio.c
1504
src/sf_nio.c
File diff suppressed because it is too large
Load Diff
111
src/sf_nio.h
111
src/sf_nio.h
|
|
@ -22,13 +22,8 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "fastcommon/fast_task_queue.h"
|
#include "fastcommon/fast_task_queue.h"
|
||||||
#include "fastcommon/ioevent_loop.h"
|
|
||||||
#include "sf_define.h"
|
#include "sf_define.h"
|
||||||
#include "sf_types.h"
|
#include "sf_types.h"
|
||||||
#include "sf_global.h"
|
|
||||||
|
|
||||||
#define SF_CTX (task->handler->fh->ctx)
|
|
||||||
#define SF_NET_BUFFER_CFG SF_CTX->net_buffer_cfg
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
@ -36,63 +31,50 @@ extern "C" {
|
||||||
|
|
||||||
void sf_set_parameters_ex(SFContext *sf_context, const int header_size,
|
void sf_set_parameters_ex(SFContext *sf_context, const int header_size,
|
||||||
sf_set_body_length_callback set_body_length_func,
|
sf_set_body_length_callback set_body_length_func,
|
||||||
sf_alloc_recv_buffer_callback alloc_recv_buffer_func,
|
sf_deal_task_func deal_func, TaskCleanUpCallback cleanup_func,
|
||||||
sf_send_done_callback send_done_callback,
|
|
||||||
sf_deal_task_callback deal_func, TaskCleanUpCallback cleanup_func,
|
|
||||||
sf_recv_timeout_callback timeout_callback, sf_release_buffer_callback
|
sf_recv_timeout_callback timeout_callback, sf_release_buffer_callback
|
||||||
release_buffer_callback);
|
release_buffer_callback);
|
||||||
|
|
||||||
#define sf_set_parameters(header_size, set_body_length_func, \
|
#define sf_set_parameters(header_size, set_body_length_func, \
|
||||||
alloc_recv_buffer_func, deal_func, cleanup_func, timeout_callback) \
|
deal_func, cleanup_func, timeout_callback) \
|
||||||
sf_set_parameters_ex(&g_sf_context, header_size, \
|
sf_set_parameters_ex(&g_sf_context, header_size, \
|
||||||
set_body_length_func, alloc_recv_buffer_func, \
|
set_body_length_func, deal_func, \
|
||||||
deal_func, cleanup_func, timeout_callback, NULL)
|
cleanup_func, timeout_callback, NULL)
|
||||||
|
|
||||||
static inline void sf_set_deal_task_callback_ex(SFContext *sf_context,
|
static inline void sf_set_deal_task_func_ex(SFContext *sf_context,
|
||||||
sf_deal_task_callback deal_func)
|
sf_deal_task_func deal_func)
|
||||||
{
|
{
|
||||||
sf_context->callbacks.deal_task = deal_func;
|
sf_context->deal_task = deal_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_set_deal_task_callback(deal_func) \
|
#define sf_set_deal_task_func(deal_func) \
|
||||||
sf_set_deal_task_callback_ex(&g_sf_context, deal_func)
|
sf_set_deal_task_func_ex(&g_sf_context, deal_func)
|
||||||
|
|
||||||
|
static inline void sf_set_remove_from_ready_list_ex(SFContext *sf_context,
|
||||||
static inline void sf_set_connect_done_callback_ex(SFContext *sf_context,
|
const bool enabled)
|
||||||
sf_connect_done_callback done_callback)
|
|
||||||
{
|
{
|
||||||
sf_context->callbacks.connect_done = done_callback;
|
sf_context->remove_from_ready_list = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_set_connect_done_callback(done_callback) \
|
#define sf_set_remove_from_ready_list(enabled) \
|
||||||
sf_set_connect_done_callback_ex(&g_sf_context, done_callback)
|
sf_set_remove_from_ready_list_ex(&g_sf_context, enabled);
|
||||||
|
|
||||||
|
static inline TaskCleanUpCallback sf_get_task_cleanup_func_ex(
|
||||||
static inline TaskCleanUpCallback sf_get_task_cleanup_callback_ex(
|
|
||||||
SFContext *sf_context)
|
SFContext *sf_context)
|
||||||
{
|
{
|
||||||
return sf_context->callbacks.task_cleanup;
|
return sf_context->task_cleanup_func;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_get_task_cleanup_callback() \
|
#define sf_get_task_cleanup_func() \
|
||||||
sf_get_task_cleanup_callback_ex(&g_sf_context)
|
sf_get_task_cleanup_func_ex(&g_sf_context)
|
||||||
|
|
||||||
#define sf_nio_task_send_done(task) \
|
#define sf_nio_task_is_idle(task) \
|
||||||
(task->send.ptr->offset == 0 && task->send.ptr->length == 0)
|
(task->offset == 0 && task->length == 0)
|
||||||
|
|
||||||
static inline void sf_nio_reset_task_length(struct fast_task_info *task)
|
void sf_recv_notify_read(int sock, short event, void *arg);
|
||||||
{
|
|
||||||
task->send.ptr->length = 0;
|
|
||||||
task->send.ptr->offset = 0;
|
|
||||||
if (task->recv.ptr != task->send.ptr) {
|
|
||||||
task->recv.ptr->length = 0;
|
|
||||||
task->recv.ptr->offset = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_socket_close_connection(struct fast_task_info *task);
|
|
||||||
void sf_recv_notify_read(int sock, const int event, void *arg);
|
|
||||||
int sf_send_add_event(struct fast_task_info *task);
|
int sf_send_add_event(struct fast_task_info *task);
|
||||||
|
int sf_client_sock_write(int sock, short event, void *arg);
|
||||||
|
int sf_client_sock_read(int sock, short event, void *arg);
|
||||||
|
|
||||||
void sf_task_finish_clean_up(struct fast_task_info *task);
|
void sf_task_finish_clean_up(struct fast_task_info *task);
|
||||||
|
|
||||||
|
|
@ -105,42 +87,6 @@ void sf_task_switch_thread(struct fast_task_info *task,
|
||||||
|
|
||||||
void sf_task_detach_thread(struct fast_task_info *task);
|
void sf_task_detach_thread(struct fast_task_info *task);
|
||||||
|
|
||||||
static inline int sf_set_body_length(struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
if (SF_CTX->callbacks.set_body_length(task) != 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (task->recv.ptr->length < 0) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"client ip: %s, pkg length: %d < 0",
|
|
||||||
__LINE__, task->client_ip,
|
|
||||||
task->recv.ptr->length);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
task->recv.ptr->length += SF_CTX->header_size;
|
|
||||||
if (task->recv.ptr->length > SF_NET_BUFFER_CFG.max_pkg_size) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"client ip: %s, pkg length: %d > "
|
|
||||||
"max pkg size: %d", __LINE__,
|
|
||||||
task->client_ip, task->recv.ptr->length,
|
|
||||||
SF_NET_BUFFER_CFG.max_pkg_size);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_socket_async_connect_server(struct fast_task_info *task);
|
|
||||||
int sf_socket_async_connect_check(struct fast_task_info *task);
|
|
||||||
|
|
||||||
ssize_t sf_socket_send_data(struct fast_task_info *task,
|
|
||||||
SFCommAction *action, bool *send_done);
|
|
||||||
ssize_t sf_socket_recv_data(struct fast_task_info *task,
|
|
||||||
const bool call_post_recv, SFCommAction *action);
|
|
||||||
|
|
||||||
int sf_rdma_busy_polling_callback(struct nio_thread_data *thread_data);
|
|
||||||
|
|
||||||
static inline int sf_nio_forward_request(struct fast_task_info *task,
|
static inline int sf_nio_forward_request(struct fast_task_info *task,
|
||||||
const int new_thread_index)
|
const int new_thread_index)
|
||||||
{
|
{
|
||||||
|
|
@ -148,18 +94,11 @@ static inline int sf_nio_forward_request(struct fast_task_info *task,
|
||||||
return sf_nio_notify(task, SF_NIO_STAGE_FORWARDED);
|
return sf_nio_notify(task, SF_NIO_STAGE_FORWARDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sf_nio_add_to_deleted_list(struct nio_thread_data
|
static inline bool sf_client_sock_in_read_stage(struct fast_task_info *task)
|
||||||
*thread_data, struct fast_task_info *task)
|
|
||||||
{
|
{
|
||||||
if (task->thread_data == thread_data) {
|
return (task->event.callback == (IOEventCallback)sf_client_sock_read);
|
||||||
ioevent_add_to_deleted_list(task);
|
|
||||||
} else {
|
|
||||||
sf_nio_notify(task, SF_NIO_STAGE_CLOSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool sf_client_sock_in_read_stage(struct fast_task_info *task);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@
|
||||||
#include "sf_ordered_writer.h"
|
#include "sf_ordered_writer.h"
|
||||||
|
|
||||||
#define deal_binlog_one_record(writer, wb) \
|
#define deal_binlog_one_record(writer, wb) \
|
||||||
sf_file_writer_deal_versioned_buffer(&(writer)->fw, &wb->bf, wb->version)
|
sf_file_writer_deal_buffer(&(writer)->fw, &wb->bf, wb->version)
|
||||||
|
|
||||||
static inline int flush_writer_files(SFOrderedWriterInfo *writer)
|
static inline int flush_writer_files(SFOrderedWriterInfo *writer)
|
||||||
{
|
{
|
||||||
|
|
@ -106,7 +106,7 @@ void sf_ordered_writer_finish(SFOrderedWriterContext *ctx)
|
||||||
{
|
{
|
||||||
int count;
|
int count;
|
||||||
|
|
||||||
if (ctx->writer.fw.file.name.str != NULL) {
|
if (ctx->writer.fw.file.name != NULL) {
|
||||||
fc_queue_terminate(&ctx->thread.queues.version);
|
fc_queue_terminate(&ctx->thread.queues.version);
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
@ -120,8 +120,8 @@ void sf_ordered_writer_finish(SFOrderedWriterContext *ctx)
|
||||||
__LINE__, ctx->writer.fw.cfg.subdir_name);
|
__LINE__, ctx->writer.fw.cfg.subdir_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(ctx->writer.fw.file.name.str);
|
free(ctx->writer.fw.file.name);
|
||||||
ctx->writer.fw.file.name.str = NULL;
|
ctx->writer.fw.file.name = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->writer.fw.file.fd >= 0) {
|
if (ctx->writer.fw.file.fd >= 0) {
|
||||||
|
|
@ -142,7 +142,8 @@ static void *binlog_writer_func(void *arg)
|
||||||
#ifdef OS_LINUX
|
#ifdef OS_LINUX
|
||||||
{
|
{
|
||||||
char thread_name[64];
|
char thread_name[64];
|
||||||
fc_combine_two_strings(thread->name, "writer", '-', thread_name);
|
snprintf(thread_name, sizeof(thread_name),
|
||||||
|
"%s-writer", thread->name);
|
||||||
prctl(PR_SET_NAME, thread_name);
|
prctl(PR_SET_NAME, thread_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -178,18 +179,12 @@ static int binlog_wbuffer_alloc_init(void *element, void *args)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int push_compare_buffer_version(const SFOrderedWriterBuffer *entry1,
|
static int compare_buffer_version(const SFOrderedWriterBuffer *entry1,
|
||||||
const SFOrderedWriterBuffer *entry2)
|
const SFOrderedWriterBuffer *entry2)
|
||||||
{
|
{
|
||||||
return fc_compare_int64(entry1->version, entry2->version);
|
return fc_compare_int64(entry1->version, entry2->version);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pop_compare_buffer_version(const SFOrderedWriterBuffer *entry,
|
|
||||||
const SFOrderedWriterBuffer *less_equal, void *arg)
|
|
||||||
{
|
|
||||||
return fc_compare_int64(entry->version, less_equal->version);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sf_ordered_writer_init_thread(SFOrderedWriterContext *context,
|
static int sf_ordered_writer_init_thread(SFOrderedWriterContext *context,
|
||||||
const char *name, const int max_record_size)
|
const char *name, const int max_record_size)
|
||||||
{
|
{
|
||||||
|
|
@ -202,7 +197,7 @@ static int sf_ordered_writer_init_thread(SFOrderedWriterContext *context,
|
||||||
|
|
||||||
thread = &context->thread;
|
thread = &context->thread;
|
||||||
writer = &context->writer;
|
writer = &context->writer;
|
||||||
fc_safe_strcpy(thread->name, name);
|
snprintf(thread->name, sizeof(thread->name), "%s", name);
|
||||||
writer->fw.cfg.max_record_size = max_record_size;
|
writer->fw.cfg.max_record_size = max_record_size;
|
||||||
writer->thread = thread;
|
writer->thread = thread;
|
||||||
|
|
||||||
|
|
@ -228,11 +223,9 @@ static int sf_ordered_writer_init_thread(SFOrderedWriterContext *context,
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=sorted_queue_init(&thread->queues.buffer, (unsigned long)
|
if ((result=sorted_queue_init(&thread->queues.buffer, (unsigned long)
|
||||||
(&((SFOrderedWriterBuffer *)NULL)->dlink),
|
(&((SFOrderedWriterBuffer *)NULL)->next),
|
||||||
(int (*)(const void *, const void *))
|
(int (*)(const void *, const void *))
|
||||||
push_compare_buffer_version,
|
compare_buffer_version)) != 0)
|
||||||
(int (*)(const void *, const void *, void *arg))
|
|
||||||
pop_compare_buffer_version, NULL)) != 0)
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
@ -241,16 +234,13 @@ static int sf_ordered_writer_init_thread(SFOrderedWriterContext *context,
|
||||||
context, SF_G_THREAD_STACK_SIZE);
|
context, SF_G_THREAD_STACK_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_ordered_writer_init_ex(SFOrderedWriterContext *context,
|
int sf_ordered_writer_init(SFOrderedWriterContext *context,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int buffer_size,
|
const int buffer_size, const int max_record_size)
|
||||||
const int max_record_size, const int64_t file_rotate_size,
|
|
||||||
const bool call_fsync)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
if ((result=sf_file_writer_init(&context->writer.fw, data_path,
|
if ((result=sf_file_writer_init_normal(&context->writer.fw,
|
||||||
subdir_name, file_prefix, max_record_size,
|
data_path, subdir_name, buffer_size)) != 0)
|
||||||
buffer_size, file_rotate_size, call_fsync)) != 0)
|
|
||||||
{
|
{
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ typedef struct sf_writer_version_entry {
|
||||||
typedef struct sf_ordered_writer_buffer {
|
typedef struct sf_ordered_writer_buffer {
|
||||||
int64_t version;
|
int64_t version;
|
||||||
BufferInfo bf;
|
BufferInfo bf;
|
||||||
struct fc_list_head dlink;
|
struct sf_ordered_writer_buffer *next;
|
||||||
} SFOrderedWriterBuffer;
|
} SFOrderedWriterBuffer;
|
||||||
|
|
||||||
typedef struct sf_orderd_writer_thread {
|
typedef struct sf_orderd_writer_thread {
|
||||||
|
|
@ -62,17 +62,9 @@ typedef struct sf_ordered_writer_context {
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int sf_ordered_writer_init_ex(SFOrderedWriterContext *context,
|
int sf_ordered_writer_init(SFOrderedWriterContext *context,
|
||||||
const char *data_path, const char *subdir_name,
|
const char *data_path, const char *subdir_name,
|
||||||
const char *file_prefix, const int buffer_size,
|
const int buffer_size, const int max_record_size);
|
||||||
const int max_record_size, const int64_t file_rotate_size,
|
|
||||||
const bool call_fsync);
|
|
||||||
|
|
||||||
#define sf_ordered_writer_init(context, data_path, \
|
|
||||||
subdir_name, buffer_size, max_record_size) \
|
|
||||||
sf_ordered_writer_init_ex(context, data_path, subdir_name, \
|
|
||||||
SF_BINLOG_FILE_PREFIX_STR, buffer_size, max_record_size, \
|
|
||||||
SF_BINLOG_DEFAULT_ROTATE_SIZE, true)
|
|
||||||
|
|
||||||
#define sf_ordered_writer_set_flags(ctx, flags) \
|
#define sf_ordered_writer_set_flags(ctx, flags) \
|
||||||
sf_file_writer_set_flags(&(ctx)->writer.fw, flags)
|
sf_file_writer_set_flags(&(ctx)->writer.fw, flags)
|
||||||
|
|
@ -125,11 +117,10 @@ static inline SFOrderedWriterBuffer *sf_ordered_writer_alloc_buffer(
|
||||||
#define sf_ordered_writer_set_binlog_index(ctx, binlog_index) \
|
#define sf_ordered_writer_set_binlog_index(ctx, binlog_index) \
|
||||||
sf_file_writer_set_binlog_index(&(ctx)->writer.fw, binlog_index)
|
sf_file_writer_set_binlog_index(&(ctx)->writer.fw, binlog_index)
|
||||||
|
|
||||||
#define sf_ordered_writer_push_to_thread_queue(ctx, buffer) \
|
#define sf_push_to_binlog_thread_queue(ctx, buffer) \
|
||||||
sorted_queue_push(&(ctx)->thread.queues.buffer, buffer)
|
sorted_queue_push(&(ctx)->thread.queues.buffer, buffer)
|
||||||
|
|
||||||
static inline void sf_ordered_writer_push_to_queue(
|
static inline void sf_push_to_binlog_write_queue(SFOrderedWriterContext *ctx,
|
||||||
SFOrderedWriterContext *ctx,
|
|
||||||
SFOrderedWriterBuffer *buffer)
|
SFOrderedWriterBuffer *buffer)
|
||||||
{
|
{
|
||||||
sorted_queue_push(&ctx->thread.queues.buffer, buffer);
|
sorted_queue_push(&ctx->thread.queues.buffer, buffer);
|
||||||
|
|
|
||||||
205
src/sf_proto.c
205
src/sf_proto.c
|
|
@ -14,6 +14,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "fastcommon/shared_func.h"
|
||||||
#include "sf_util.h"
|
#include "sf_util.h"
|
||||||
#include "sf_nio.h"
|
#include "sf_nio.h"
|
||||||
#include "sf_proto.h"
|
#include "sf_proto.h"
|
||||||
|
|
@ -27,23 +29,19 @@ static int64_t log_slower_than_us = 0;
|
||||||
int sf_proto_set_body_length(struct fast_task_info *task)
|
int sf_proto_set_body_length(struct fast_task_info *task)
|
||||||
{
|
{
|
||||||
SFCommonProtoHeader *header;
|
SFCommonProtoHeader *header;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
header = (SFCommonProtoHeader *)task->recv.ptr->data;
|
header = (SFCommonProtoHeader *)task->data;
|
||||||
if (!SF_PROTO_CHECK_MAGIC(header->magic)) {
|
if (!SF_PROTO_CHECK_MAGIC(header->magic)) {
|
||||||
format_ip_address(task->client_ip, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"%s peer %s:%u, magic "SF_PROTO_MAGIC_FORMAT" is invalid, "
|
"peer %s:%u, magic "SF_PROTO_MAGIC_FORMAT
|
||||||
"expect: "SF_PROTO_MAGIC_FORMAT", cmd: %d, body length: %d",
|
" is invalid, expect: "SF_PROTO_MAGIC_FORMAT,
|
||||||
__LINE__, (task->handler != NULL ? task->handler->fh->ctx->
|
__LINE__, task->client_ip, task->port,
|
||||||
name : ""), formatted_ip, task->port,
|
|
||||||
SF_PROTO_MAGIC_PARAMS(header->magic),
|
SF_PROTO_MAGIC_PARAMS(header->magic),
|
||||||
SF_PROTO_MAGIC_EXPECT_PARAMS, header->cmd,
|
SF_PROTO_MAGIC_EXPECT_PARAMS);
|
||||||
buff2int(header->body_len));
|
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
task->recv.ptr->length = buff2int(header->body_len); //set body length
|
task->length = buff2int(header->body_len); //set body length
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -72,14 +70,8 @@ int sf_check_response(ConnectionInfo *conn, SFResponseInfo *response,
|
||||||
response->error.length = response->header.body_len;
|
response->error.length = response->header.body_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb_ex(conn->sock, response->error.message,
|
||||||
memcpy(response->error.message, G_RDMA_CONNECTION_CALLBACKS.
|
response->error.length, network_timeout, &recv_bytes)) == 0)
|
||||||
get_recv_buffer(conn)->buff + sizeof(SFCommonProtoHeader),
|
|
||||||
response->error.length);
|
|
||||||
response->error.message[response->error.length] = '\0';
|
|
||||||
} else if ((result=tcprecvdata_nb_ex(conn->sock, response->
|
|
||||||
error.message, response->error.length,
|
|
||||||
network_timeout, &recv_bytes)) == 0)
|
|
||||||
{
|
{
|
||||||
response->error.message[response->error.length] = '\0';
|
response->error.message[response->error.length] = '\0';
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -104,48 +96,30 @@ static inline int sf_recv_response_header(ConnectionInfo *conn,
|
||||||
SFResponseInfo *response, const int network_timeout)
|
SFResponseInfo *response, const int network_timeout)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
BufferInfo *buffer;
|
|
||||||
SFCommonProtoHeader header_proto;
|
SFCommonProtoHeader header_proto;
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb(conn->sock, &header_proto,
|
||||||
buffer = G_RDMA_CONNECTION_CALLBACKS.get_recv_buffer(conn);
|
sizeof(SFCommonProtoHeader), network_timeout)) != 0)
|
||||||
if (buffer->length < sizeof(SFCommonProtoHeader)) {
|
{
|
||||||
response->error.length = sprintf(response->error.message,
|
response->error.length = snprintf(response->error.message,
|
||||||
"recv pkg length: %d < header size: %d",
|
sizeof(response->error.message),
|
||||||
buffer->length, (int)sizeof(SFCommonProtoHeader));
|
"recv data fail, errno: %d, error info: %s",
|
||||||
return EINVAL;
|
result, STRERROR(result));
|
||||||
}
|
return result;
|
||||||
|
|
||||||
if ((result=sf_proto_parse_header((SFCommonProtoHeader *)
|
|
||||||
buffer->buff, response)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buffer->length != (sizeof(SFCommonProtoHeader) +
|
|
||||||
response->header.body_len))
|
|
||||||
{
|
|
||||||
response->error.length = snprintf(response->error.message,
|
|
||||||
sizeof(response->error.message),
|
|
||||||
"recv package length: %d != calculate: %d",
|
|
||||||
buffer->length, (int)(sizeof(SFCommonProtoHeader) +
|
|
||||||
response->header.body_len));
|
|
||||||
return EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
if ((result=tcprecvdata_nb(conn->sock, &header_proto,
|
|
||||||
sizeof(SFCommonProtoHeader), network_timeout)) != 0)
|
|
||||||
{
|
|
||||||
response->error.length = snprintf(response->error.message,
|
|
||||||
sizeof(response->error.message),
|
|
||||||
"recv data fail, errno: %d, error info: %s",
|
|
||||||
result, STRERROR(result));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return sf_proto_parse_header(&header_proto, response);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!SF_PROTO_CHECK_MAGIC(header_proto.magic)) {
|
||||||
|
response->error.length = snprintf(response->error.message,
|
||||||
|
sizeof(response->error.message),
|
||||||
|
"magic "SF_PROTO_MAGIC_FORMAT" is invalid, "
|
||||||
|
"expect: "SF_PROTO_MAGIC_FORMAT,
|
||||||
|
SF_PROTO_MAGIC_PARAMS(header_proto.magic),
|
||||||
|
SF_PROTO_MAGIC_EXPECT_PARAMS);
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf_proto_extract_header(&header_proto, &response->header);
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data,
|
int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data,
|
||||||
|
|
@ -153,9 +127,11 @@ int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data,
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result=sf_proto_send_buf1(conn, data, len,
|
if ((result=tcpsenddata_nb(conn->sock, data, len, network_timeout)) != 0) {
|
||||||
response, network_timeout)) != 0)
|
response->error.length = snprintf(response->error.message,
|
||||||
{
|
sizeof(response->error.message),
|
||||||
|
"send data fail, errno: %d, error info: %s",
|
||||||
|
result, STRERROR(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,10 +194,7 @@ int sf_send_and_recv_response_ex(ConnectionInfo *conn, char *send_data,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, response->
|
||||||
memcpy(recv_data, G_RDMA_CONNECTION_CALLBACKS.get_recv_buffer(conn)->
|
|
||||||
buff + sizeof(SFCommonProtoHeader), response->header.body_len);
|
|
||||||
} else if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, response->
|
|
||||||
header.body_len, network_timeout, &recv_bytes)) != 0)
|
header.body_len, network_timeout, &recv_bytes)) != 0)
|
||||||
{
|
{
|
||||||
response->error.length = snprintf(response->error.message,
|
response->error.length = snprintf(response->error.message,
|
||||||
|
|
@ -261,11 +234,7 @@ int sf_send_and_recv_response_ex1(ConnectionInfo *conn, char *send_data,
|
||||||
return EOVERFLOW;
|
return EOVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, response->
|
||||||
memcpy(recv_data, G_RDMA_CONNECTION_CALLBACKS.get_recv_buffer(conn)->
|
|
||||||
buff + sizeof(SFCommonProtoHeader), response->header.body_len);
|
|
||||||
*body_len = response->header.body_len;
|
|
||||||
} else if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, response->
|
|
||||||
header.body_len, network_timeout, body_len)) != 0)
|
header.body_len, network_timeout, body_len)) != 0)
|
||||||
{
|
{
|
||||||
response->error.length = snprintf(response->error.message,
|
response->error.length = snprintf(response->error.message,
|
||||||
|
|
@ -306,10 +275,7 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, expect_body_len,
|
||||||
memcpy(recv_data, G_RDMA_CONNECTION_CALLBACKS.get_recv_buffer(conn)->
|
|
||||||
buff + sizeof(SFCommonProtoHeader), response->header.body_len);
|
|
||||||
} else if ((result=tcprecvdata_nb_ex(conn->sock, recv_data, expect_body_len,
|
|
||||||
network_timeout, &recv_bytes)) != 0)
|
network_timeout, &recv_bytes)) != 0)
|
||||||
{
|
{
|
||||||
response->error.length = snprintf(response->error.message,
|
response->error.length = snprintf(response->error.message,
|
||||||
|
|
@ -377,10 +343,7 @@ int sf_recv_vary_response(ConnectionInfo *conn, SFResponseInfo *response,
|
||||||
buffer->alloc_size = alloc_size;
|
buffer->alloc_size = alloc_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
if ((result=tcprecvdata_nb_ex(conn->sock, buffer->buff, response->
|
||||||
memcpy(buffer->buff, G_RDMA_CONNECTION_CALLBACKS.get_recv_buffer(conn)->
|
|
||||||
buff + sizeof(SFCommonProtoHeader), response->header.body_len);
|
|
||||||
} else if ((result=tcprecvdata_nb_ex(conn->sock, buffer->buff, response->
|
|
||||||
header.body_len, network_timeout, &recv_bytes)) != 0)
|
header.body_len, network_timeout, &recv_bytes)) != 0)
|
||||||
{
|
{
|
||||||
response->error.length = snprintf(response->error.message,
|
response->error.length = snprintf(response->error.message,
|
||||||
|
|
@ -401,9 +364,13 @@ int sf_send_and_recv_vary_response(ConnectionInfo *conn,
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if ((result=sf_proto_send_buf1(conn, send_data, send_len,
|
if ((result=tcpsenddata_nb(conn->sock, send_data,
|
||||||
response, network_timeout)) != 0)
|
send_len, network_timeout)) != 0)
|
||||||
{
|
{
|
||||||
|
response->error.length = snprintf(response->error.message,
|
||||||
|
sizeof(response->error.message),
|
||||||
|
"send data fail, errno: %d, error info: %s",
|
||||||
|
result, STRERROR(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -444,10 +411,6 @@ const char *sf_get_cmd_caption(const int cmd)
|
||||||
return "GET_LEADER_REQ";
|
return "GET_LEADER_REQ";
|
||||||
case SF_SERVICE_PROTO_GET_LEADER_RESP:
|
case SF_SERVICE_PROTO_GET_LEADER_RESP:
|
||||||
return "GET_LEADER_RESP";
|
return "GET_LEADER_RESP";
|
||||||
case SF_CLUSTER_PROTO_GET_SERVER_STATUS_REQ:
|
|
||||||
return "GET_SERVER_STATUS_REQ";
|
|
||||||
case SF_CLUSTER_PROTO_GET_SERVER_STATUS_RESP:
|
|
||||||
return "GET_SERVER_STATUS_RESP";
|
|
||||||
default:
|
default:
|
||||||
return "UNKOWN";
|
return "UNKOWN";
|
||||||
}
|
}
|
||||||
|
|
@ -456,17 +419,14 @@ const char *sf_get_cmd_caption(const int cmd)
|
||||||
int sf_proto_deal_ack(struct fast_task_info *task,
|
int sf_proto_deal_ack(struct fast_task_info *task,
|
||||||
SFRequestInfo *request, SFResponseInfo *response)
|
SFRequestInfo *request, SFResponseInfo *response)
|
||||||
{
|
{
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
|
|
||||||
if (request->header.status != 0) {
|
if (request->header.status != 0) {
|
||||||
if (request->header.body_len > 0) {
|
if (request->header.body_len > 0) {
|
||||||
int remain_size;
|
int remain_size;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
format_ip_address(task->client_ip, formatted_ip);
|
|
||||||
response->error.length = sprintf(response->error.message,
|
response->error.length = sprintf(response->error.message,
|
||||||
"message from peer %s:%u => ",
|
"message from peer %s:%u => ",
|
||||||
formatted_ip, task->port);
|
task->client_ip, task->port);
|
||||||
remain_size = sizeof(response->error.message) -
|
remain_size = sizeof(response->error.message) -
|
||||||
response->error.length;
|
response->error.length;
|
||||||
if (request->header.body_len >= remain_size) {
|
if (request->header.body_len >= remain_size) {
|
||||||
|
|
@ -494,8 +454,7 @@ int sf_proto_deal_ack(struct fast_task_info *task,
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_proto_rebind_idempotency_channel(ConnectionInfo *conn,
|
int sf_proto_rebind_idempotency_channel(ConnectionInfo *conn,
|
||||||
const char *service_name, const uint32_t channel_id,
|
const uint32_t channel_id, const int key, const int network_timeout)
|
||||||
const int key, const int network_timeout)
|
|
||||||
{
|
{
|
||||||
char out_buff[sizeof(SFCommonProtoHeader) +
|
char out_buff[sizeof(SFCommonProtoHeader) +
|
||||||
sizeof(SFProtoRebindChannelReq)];
|
sizeof(SFProtoRebindChannelReq)];
|
||||||
|
|
@ -515,20 +474,19 @@ int sf_proto_rebind_idempotency_channel(ConnectionInfo *conn,
|
||||||
sizeof(out_buff), &response, network_timeout,
|
sizeof(out_buff), &response, network_timeout,
|
||||||
SF_SERVICE_PROTO_REBIND_CHANNEL_RESP)) != 0)
|
SF_SERVICE_PROTO_REBIND_CHANNEL_RESP)) != 0)
|
||||||
{
|
{
|
||||||
sf_log_network_error(&response, conn, service_name, result);
|
sf_log_network_error(&response, conn, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_proto_get_group_servers(ConnectionInfo *conn,
|
int sf_proto_get_group_servers(ConnectionInfo *conn,
|
||||||
const char *service_name, const int network_timeout,
|
const int network_timeout, const int group_id,
|
||||||
const int group_id, SFGroupServerArray *sarray)
|
SFGroupServerArray *sarray)
|
||||||
{
|
{
|
||||||
char out_buff[sizeof(SFCommonProtoHeader) +
|
char out_buff[sizeof(SFCommonProtoHeader) +
|
||||||
sizeof(SFProtoGetGroupServersReq)];
|
sizeof(SFProtoGetGroupServersReq)];
|
||||||
char in_buff[1024];
|
char in_buff[1024];
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
SFCommonProtoHeader *header;
|
SFCommonProtoHeader *header;
|
||||||
SFProtoGetGroupServersReq *req;
|
SFProtoGetGroupServersReq *req;
|
||||||
SFProtoGetGroupServersRespBodyHeader *body_header;
|
SFProtoGetGroupServersRespBodyHeader *body_header;
|
||||||
|
|
@ -551,15 +509,14 @@ int sf_proto_get_group_servers(ConnectionInfo *conn,
|
||||||
SF_SERVICE_PROTO_GET_GROUP_SERVERS_RESP, in_buff,
|
SF_SERVICE_PROTO_GET_GROUP_SERVERS_RESP, in_buff,
|
||||||
sizeof(in_buff), &body_len)) != 0)
|
sizeof(in_buff), &body_len)) != 0)
|
||||||
{
|
{
|
||||||
sf_log_network_error(&response, conn, service_name, result);
|
sf_log_network_error(&response, conn, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body_len < sizeof(SFProtoGetGroupServersRespBodyHeader)) {
|
if (body_len < sizeof(SFProtoGetGroupServersRespBodyHeader)) {
|
||||||
format_ip_address(conn->ip_addr, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"server %s:%u response body length: %d < %d",
|
"server %s:%d response body length: %d < %d",
|
||||||
__LINE__, formatted_ip, conn->port, body_len,
|
__LINE__, conn->ip_addr, conn->port, body_len,
|
||||||
(int)sizeof(SFProtoGetGroupServersRespBodyHeader));
|
(int)sizeof(SFProtoGetGroupServersRespBodyHeader));
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
|
|
@ -567,17 +524,15 @@ int sf_proto_get_group_servers(ConnectionInfo *conn,
|
||||||
body_header = (SFProtoGetGroupServersRespBodyHeader *)in_buff;
|
body_header = (SFProtoGetGroupServersRespBodyHeader *)in_buff;
|
||||||
count = buff2int(body_header->count);
|
count = buff2int(body_header->count);
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
format_ip_address(conn->ip_addr, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"server %s:%u response server count: %d <= 0",
|
"server %s:%d response server count: %d <= 0",
|
||||||
__LINE__, formatted_ip, conn->port, count);
|
__LINE__, conn->ip_addr, conn->port, count);
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
}
|
}
|
||||||
if (count > sarray->alloc) {
|
if (count > sarray->alloc) {
|
||||||
format_ip_address(conn->ip_addr, formatted_ip);
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"server %s:%u response server count: %d is too large, "
|
"server %s:%d response server count: %d is too large, "
|
||||||
"exceeds %d", __LINE__, formatted_ip, conn->port,
|
"exceeds %d", __LINE__, conn->ip_addr, conn->port,
|
||||||
count, sarray->alloc);
|
count, sarray->alloc);
|
||||||
return EOVERFLOW;
|
return EOVERFLOW;
|
||||||
}
|
}
|
||||||
|
|
@ -594,8 +549,9 @@ int sf_proto_get_group_servers(ConnectionInfo *conn,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_proto_get_leader(ConnectionInfo *conn, const char *service_name,
|
int sf_proto_get_leader(ConnectionInfo *conn,
|
||||||
const int network_timeout, SFClientServerEntry *leader)
|
const int network_timeout,
|
||||||
|
SFClientServerEntry *leader)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
SFCommonProtoHeader *header;
|
SFCommonProtoHeader *header;
|
||||||
|
|
@ -611,13 +567,12 @@ int sf_proto_get_leader(ConnectionInfo *conn, const char *service_name,
|
||||||
SF_SERVICE_PROTO_GET_LEADER_RESP, (char *)&server_resp,
|
SF_SERVICE_PROTO_GET_LEADER_RESP, (char *)&server_resp,
|
||||||
sizeof(SFProtoGetServerResp))) != 0)
|
sizeof(SFProtoGetServerResp))) != 0)
|
||||||
{
|
{
|
||||||
sf_log_network_error(&response, conn, service_name, result);
|
sf_log_network_error(&response, conn, result);
|
||||||
} else {
|
} else {
|
||||||
leader->server_id = buff2int(server_resp.server_id);
|
leader->server_id = buff2int(server_resp.server_id);
|
||||||
memcpy(leader->conn.ip_addr, server_resp.ip_addr, IP_ADDRESS_SIZE);
|
memcpy(leader->conn.ip_addr, server_resp.ip_addr, IP_ADDRESS_SIZE);
|
||||||
*(leader->conn.ip_addr + IP_ADDRESS_SIZE - 1) = '\0';
|
*(leader->conn.ip_addr + IP_ADDRESS_SIZE - 1) = '\0';
|
||||||
leader->conn.port = buff2short(server_resp.port);
|
leader->conn.port = buff2short(server_resp.port);
|
||||||
leader->conn.comm_type = conn->comm_type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -630,22 +585,20 @@ void sf_proto_set_handler_context(const SFHandlerContext *ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_proto_deal_task_done(struct fast_task_info *task,
|
int sf_proto_deal_task_done(struct fast_task_info *task,
|
||||||
const char *service_name, SFCommonTaskContext *ctx)
|
SFCommonTaskContext *ctx)
|
||||||
{
|
{
|
||||||
SFCommonProtoHeader *proto_header;
|
SFCommonProtoHeader *proto_header;
|
||||||
int status;
|
int status;
|
||||||
int r;
|
int r;
|
||||||
int64_t time_used;
|
int64_t time_used;
|
||||||
int log_level;
|
int log_level;
|
||||||
char formatted_ip[FORMATTED_IP_SIZE];
|
|
||||||
char time_buff[32];
|
char time_buff[32];
|
||||||
|
|
||||||
if (ctx->log_level != LOG_NOTHING && ctx->response.error.length > 0) {
|
if (ctx->log_level != LOG_NOTHING && ctx->response.error.length > 0) {
|
||||||
log_it_ex(&g_log_context, ctx->log_level,
|
log_it_ex(&g_log_context, ctx->log_level,
|
||||||
"file: "__FILE__", line: %d, %s "
|
"file: "__FILE__", line: %d, "
|
||||||
"peer %s:%u, cmd: %d (%s), req body length: %d, "
|
"peer %s:%u, cmd: %d (%s), req body length: %d, "
|
||||||
"resp status: %d, %s", __LINE__, service_name,
|
"resp status: %d, %s", __LINE__, task->client_ip,
|
||||||
format_ip_address(task->client_ip, formatted_ip),
|
|
||||||
task->port, ctx->request.header.cmd,
|
task->port, ctx->request.header.cmd,
|
||||||
GET_CMD_CAPTION(ctx->request.header.cmd),
|
GET_CMD_CAPTION(ctx->request.header.cmd),
|
||||||
ctx->request.header.body_len, ctx->response.header.status,
|
ctx->request.header.body_len, ctx->response.header.status,
|
||||||
|
|
@ -657,38 +610,36 @@ int sf_proto_deal_task_done(struct fast_task_info *task,
|
||||||
time_used = get_current_time_us() - ctx->req_start_time;
|
time_used = get_current_time_us() - ctx->req_start_time;
|
||||||
log_level = GET_CMD_LOG_LEVEL(ctx->request.header.cmd);
|
log_level = GET_CMD_LOG_LEVEL(ctx->request.header.cmd);
|
||||||
log_it_ex(&g_log_context, log_level, "file: "__FILE__", line: %d, "
|
log_it_ex(&g_log_context, log_level, "file: "__FILE__", line: %d, "
|
||||||
"%s client %s:%u, req cmd: %d (%s), req body_len: %d, "
|
"client %s:%u, req cmd: %d (%s), req body_len: %d, "
|
||||||
"resp status: %d, time used: %s us", __LINE__, service_name,
|
"resp status: %d, time used: %s us", __LINE__,
|
||||||
format_ip_address(task->client_ip, formatted_ip),
|
task->client_ip, task->port, ctx->request.header.cmd,
|
||||||
task->port, ctx->request.header.cmd,
|
|
||||||
GET_CMD_CAPTION(ctx->request.header.cmd),
|
GET_CMD_CAPTION(ctx->request.header.cmd),
|
||||||
ctx->request.header.body_len, ctx->response.header.status,
|
ctx->request.header.body_len, ctx->response.header.status,
|
||||||
long_to_comma_str(time_used, time_buff));
|
long_to_comma_str(time_used, time_buff));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->response.header.status == 0) {
|
if (ctx->response.header.status == 0) {
|
||||||
|
task->offset = task->length = 0;
|
||||||
return sf_set_read_event(task);
|
return sf_set_read_event(task);
|
||||||
} else {
|
} else {
|
||||||
return FC_NEGATIVE(ctx->response.header.status);
|
return FC_NEGATIVE(ctx->response.header.status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proto_header = (SFCommonProtoHeader *)task->send.ptr->data;
|
proto_header = (SFCommonProtoHeader *)task->data;
|
||||||
if (!ctx->response_done) {
|
if (!ctx->response_done) {
|
||||||
ctx->response.header.body_len = ctx->response.error.length;
|
ctx->response.header.body_len = ctx->response.error.length;
|
||||||
if (ctx->response.error.length > 0) {
|
if (ctx->response.error.length > 0) {
|
||||||
memcpy(task->send.ptr->data + sizeof(SFCommonProtoHeader),
|
memcpy(task->data + sizeof(SFCommonProtoHeader),
|
||||||
ctx->response.error.message, ctx->response.error.length);
|
ctx->response.error.message, ctx->response.error.length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
status = sf_unify_errno(FC_ABS(ctx->response.header.status));
|
status = sf_unify_errno(FC_ABS(ctx->response.header.status));
|
||||||
short2buff(status, proto_header->status);
|
short2buff(status, proto_header->status);
|
||||||
short2buff(ctx->response.header.flags, proto_header->flags);
|
|
||||||
proto_header->cmd = ctx->response.header.cmd;
|
proto_header->cmd = ctx->response.header.cmd;
|
||||||
int2buff(ctx->response.header.body_len, proto_header->body_len);
|
int2buff(ctx->response.header.body_len, proto_header->body_len);
|
||||||
task->send.ptr->length = sizeof(SFCommonProtoHeader) +
|
task->length = sizeof(SFCommonProtoHeader) + ctx->response.header.body_len;
|
||||||
ctx->response.header.body_len;
|
|
||||||
|
|
||||||
r = sf_send_add_event(task);
|
r = sf_send_add_event(task);
|
||||||
time_used = get_current_time_us() - ctx->req_start_time;
|
time_used = get_current_time_us() - ctx->req_start_time;
|
||||||
|
|
@ -698,11 +649,10 @@ int sf_proto_deal_task_done(struct fast_task_info *task,
|
||||||
char buff[256];
|
char buff[256];
|
||||||
int blen;
|
int blen;
|
||||||
|
|
||||||
blen = sprintf(buff, "timed used: %s us, %s client %s:%u, "
|
blen = sprintf(buff, "timed used: %s us, client %s:%u, "
|
||||||
"req cmd: %d (%s), req body len: %d, resp cmd: %d (%s), "
|
"req cmd: %d (%s), req body len: %d, resp cmd: %d (%s), "
|
||||||
"status: %d, resp body len: %d", long_to_comma_str(time_used,
|
"status: %d, resp body len: %d", long_to_comma_str(time_used,
|
||||||
time_buff), service_name, format_ip_address(task->
|
time_buff), task->client_ip, task->port, ctx->request.
|
||||||
client_ip, formatted_ip), task->port, ctx->request.
|
|
||||||
header.cmd, GET_CMD_CAPTION(ctx->request.header.cmd),
|
header.cmd, GET_CMD_CAPTION(ctx->request.header.cmd),
|
||||||
ctx->request.header.body_len, ctx->response.header.cmd,
|
ctx->request.header.body_len, ctx->response.header.cmd,
|
||||||
GET_CMD_CAPTION(ctx->response.header.cmd),
|
GET_CMD_CAPTION(ctx->response.header.cmd),
|
||||||
|
|
@ -713,11 +663,10 @@ int sf_proto_deal_task_done(struct fast_task_info *task,
|
||||||
if (sf_handler_ctx.callbacks.get_cmd_log_level != NULL) {
|
if (sf_handler_ctx.callbacks.get_cmd_log_level != NULL) {
|
||||||
log_level = GET_CMD_LOG_LEVEL(ctx->request.header.cmd);
|
log_level = GET_CMD_LOG_LEVEL(ctx->request.header.cmd);
|
||||||
log_it_ex(&g_log_context, log_level, "file: "__FILE__", line: %d, "
|
log_it_ex(&g_log_context, log_level, "file: "__FILE__", line: %d, "
|
||||||
"%s client %s:%u, req cmd: %d (%s), req body_len: %d, "
|
"client %s:%u, req cmd: %d (%s), req body_len: %d, "
|
||||||
"resp cmd: %d (%s), status: %d, resp body_len: %d, "
|
"resp cmd: %d (%s), status: %d, resp body_len: %d, "
|
||||||
"time used: %s us", __LINE__, service_name,
|
"time used: %s us", __LINE__,
|
||||||
format_ip_address(task->client_ip, formatted_ip),
|
task->client_ip, task->port, ctx->request.header.cmd,
|
||||||
task->port, ctx->request.header.cmd,
|
|
||||||
GET_CMD_CAPTION(ctx->request.header.cmd),
|
GET_CMD_CAPTION(ctx->request.header.cmd),
|
||||||
ctx->request.header.body_len, ctx->response.header.cmd,
|
ctx->request.header.body_len, ctx->response.header.cmd,
|
||||||
GET_CMD_CAPTION(ctx->response.header.cmd),
|
GET_CMD_CAPTION(ctx->response.header.cmd),
|
||||||
|
|
|
||||||
369
src/sf_proto.h
369
src/sf_proto.h
|
|
@ -48,10 +48,6 @@
|
||||||
#define SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_REQ 125
|
#define SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_REQ 125
|
||||||
#define SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_RESP 126
|
#define SF_SERVICE_PROTO_REPORT_REQ_RECEIPT_RESP 126
|
||||||
|
|
||||||
#define SF_CLUSTER_PROTO_GET_SERVER_STATUS_REQ 201
|
|
||||||
#define SF_CLUSTER_PROTO_GET_SERVER_STATUS_RESP 202
|
|
||||||
|
|
||||||
|
|
||||||
#define SF_PROTO_MAGIC_CHAR '@'
|
#define SF_PROTO_MAGIC_CHAR '@'
|
||||||
#define SF_PROTO_SET_MAGIC(m) \
|
#define SF_PROTO_SET_MAGIC(m) \
|
||||||
m[0] = m[1] = m[2] = m[3] = SF_PROTO_MAGIC_CHAR
|
m[0] = m[1] = m[2] = m[3] = SF_PROTO_MAGIC_CHAR
|
||||||
|
|
@ -68,17 +64,19 @@
|
||||||
#define SF_PROTO_MAGIC_PARAMS(m) \
|
#define SF_PROTO_MAGIC_PARAMS(m) \
|
||||||
m[0], m[1], m[2], m[3]
|
m[0], m[1], m[2], m[3]
|
||||||
|
|
||||||
#define SF_PROTO_SET_HEADER_EX(header, _cmd, _flags, _body_len) \
|
#define SF_PROTO_SET_HEADER(header, _cmd, _body_len) \
|
||||||
do { \
|
do { \
|
||||||
SF_PROTO_SET_MAGIC((header)->magic); \
|
SF_PROTO_SET_MAGIC((header)->magic); \
|
||||||
(header)->cmd = _cmd; \
|
(header)->cmd = _cmd; \
|
||||||
(header)->status[0] = (header)->status[1] = 0; \
|
(header)->status[0] = (header)->status[1] = 0; \
|
||||||
short2buff(_flags, (header)->flags); \
|
|
||||||
int2buff(_body_len, (header)->body_len); \
|
int2buff(_body_len, (header)->body_len); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SF_PROTO_SET_HEADER(header, _cmd, _body_len) \
|
#define SF_PROTO_SET_HEADER_EX(header, _cmd, _flags, _body_len) \
|
||||||
SF_PROTO_SET_HEADER_EX(header, _cmd, 0, _body_len)
|
do { \
|
||||||
|
SF_PROTO_SET_HEADER(header, _cmd, _body_len); \
|
||||||
|
short2buff(_flags, (header)->flags); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#define SF_PROTO_SET_RESPONSE_HEADER(proto_header, resp_header) \
|
#define SF_PROTO_SET_RESPONSE_HEADER(proto_header, resp_header) \
|
||||||
do { \
|
do { \
|
||||||
|
|
@ -87,32 +85,22 @@
|
||||||
int2buff((resp_header).body_len, (proto_header)->body_len);\
|
int2buff((resp_header).body_len, (proto_header)->body_len);\
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
#define SF_PROTO_RESP_BODY(task) \
|
||||||
#define SF_PROTO_SEND_BODY(task) \
|
(task->data + sizeof(SFCommonProtoHeader))
|
||||||
(task->send.ptr->data + sizeof(SFCommonProtoHeader))
|
|
||||||
|
|
||||||
#define SF_PROTO_RECV_BODY(task) \
|
|
||||||
(task->recv.ptr->data + sizeof(SFCommonProtoHeader))
|
|
||||||
|
|
||||||
#define SF_RECV_BODY_LENGTH(task) \
|
|
||||||
(task->recv.ptr->length - sizeof(SFCommonProtoHeader))
|
|
||||||
|
|
||||||
#define SF_SEND_BUFF_END(task) (task->send.ptr->data + task->send.ptr->size)
|
|
||||||
#define SF_RECV_BUFF_END(task) (task->recv.ptr->data + task->recv.ptr->size)
|
|
||||||
|
|
||||||
#define SF_PROTO_UPDATE_EXTRA_BODY_SIZE \
|
#define SF_PROTO_UPDATE_EXTRA_BODY_SIZE \
|
||||||
sizeof(SFProtoIdempotencyAdditionalHeader) + FCFS_AUTH_SESSION_ID_LEN
|
sizeof(SFProtoIdempotencyAdditionalHeader) + FCFS_AUTH_SESSION_ID_LEN
|
||||||
|
|
||||||
#define SF_PROTO_QUERY_EXTRA_BODY_SIZE FCFS_AUTH_SESSION_ID_LEN
|
#define SF_PROTO_QUERY_EXTRA_BODY_SIZE FCFS_AUTH_SESSION_ID_LEN
|
||||||
|
|
||||||
#define SF_PROTO_CLIENT_SET_REQ_EX(client_ctx, auth_enabled, \
|
#define SF_PROTO_CLIENT_SET_REQ(client_ctx, out_buff, \
|
||||||
out_buff, header, req, the_req_id, out_bytes) \
|
header, req, the_req_id, out_bytes) \
|
||||||
do { \
|
do { \
|
||||||
char *the_req_start; \
|
char *the_req_start; \
|
||||||
header = (SFCommonProtoHeader *)out_buff; \
|
header = (SFCommonProtoHeader *)out_buff; \
|
||||||
the_req_start = (char *)(header + 1); \
|
the_req_start = (char *)(header + 1); \
|
||||||
out_bytes = sizeof(SFCommonProtoHeader) + sizeof(*req); \
|
out_bytes = sizeof(SFCommonProtoHeader) + sizeof(*req); \
|
||||||
if (auth_enabled) { \
|
if (client_ctx->auth.enabled) { \
|
||||||
out_bytes += FCFS_AUTH_SESSION_ID_LEN; \
|
out_bytes += FCFS_AUTH_SESSION_ID_LEN; \
|
||||||
memcpy(the_req_start, client_ctx->auth.ctx-> \
|
memcpy(the_req_start, client_ctx->auth.ctx-> \
|
||||||
session.id, FCFS_AUTH_SESSION_ID_LEN); \
|
session.id, FCFS_AUTH_SESSION_ID_LEN); \
|
||||||
|
|
@ -129,10 +117,6 @@
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SF_PROTO_CLIENT_SET_REQ(client_ctx, out_buff, \
|
|
||||||
header, req, the_req_id, out_bytes) \
|
|
||||||
SF_PROTO_CLIENT_SET_REQ_EX(client_ctx, client_ctx->auth.enabled, \
|
|
||||||
out_buff, header, req, the_req_id, out_bytes)
|
|
||||||
|
|
||||||
typedef struct sf_common_proto_header {
|
typedef struct sf_common_proto_header {
|
||||||
unsigned char magic[4]; //magic number
|
unsigned char magic[4]; //magic number
|
||||||
|
|
@ -188,8 +172,8 @@ typedef struct sf_proto_setup_channel_req {
|
||||||
typedef struct sf_proto_setup_channel_resp {
|
typedef struct sf_proto_setup_channel_resp {
|
||||||
char channel_id[4];
|
char channel_id[4];
|
||||||
char key[4];
|
char key[4];
|
||||||
char server_id[4];
|
|
||||||
char buffer_size[4];
|
char buffer_size[4];
|
||||||
|
char padding[4];
|
||||||
} SFProtoSetupChannelResp;
|
} SFProtoSetupChannelResp;
|
||||||
|
|
||||||
typedef struct sf_proto_rebind_channel_req {
|
typedef struct sf_proto_rebind_channel_req {
|
||||||
|
|
@ -206,33 +190,6 @@ typedef struct sf_proto_report_req_receipt_body {
|
||||||
char req_id[8];
|
char req_id[8];
|
||||||
} SFProtoReportReqReceiptBody;
|
} SFProtoReportReqReceiptBody;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
unsigned char servers[SF_CLUSTER_CONFIG_SIGN_LEN];
|
|
||||||
unsigned char cluster[SF_CLUSTER_CONFIG_SIGN_LEN];
|
|
||||||
} SFProtoConfigSigns;
|
|
||||||
|
|
||||||
typedef struct sf_proto_get_server_status_req {
|
|
||||||
SFProtoConfigSigns config_signs;
|
|
||||||
char server_id[4]; //my server id
|
|
||||||
union {
|
|
||||||
char is_leader;
|
|
||||||
char is_master;
|
|
||||||
};
|
|
||||||
char auth_enabled;
|
|
||||||
char padding[2];
|
|
||||||
} SFProtoGetServerStatusReq;
|
|
||||||
|
|
||||||
typedef struct sf_get_server_status_request {
|
|
||||||
const unsigned char *servers_sign;
|
|
||||||
const unsigned char *cluster_sign;
|
|
||||||
int server_id; //my server id
|
|
||||||
union {
|
|
||||||
bool is_leader;
|
|
||||||
bool is_master;
|
|
||||||
};
|
|
||||||
bool auth_enabled;
|
|
||||||
} SFGetServerStatusRequest;
|
|
||||||
|
|
||||||
typedef struct sf_group_server_info {
|
typedef struct sf_group_server_info {
|
||||||
int id;
|
int id;
|
||||||
bool is_leader;
|
bool is_leader;
|
||||||
|
|
@ -288,17 +245,7 @@ int sf_proto_set_body_length(struct fast_task_info *task);
|
||||||
const char *sf_get_cmd_caption(const int cmd);
|
const char *sf_get_cmd_caption(const int cmd);
|
||||||
|
|
||||||
int sf_proto_deal_task_done(struct fast_task_info *task,
|
int sf_proto_deal_task_done(struct fast_task_info *task,
|
||||||
const char *service_name, SFCommonTaskContext *ctx);
|
SFCommonTaskContext *ctx);
|
||||||
|
|
||||||
static inline void sf_proto_init_task_magic(struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->send.ptr->data)->magic);
|
|
||||||
if (task->recv.ptr != task->send.ptr) {
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->recv.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_proto_init_task_context(struct fast_task_info *task,
|
static inline void sf_proto_init_task_context(struct fast_task_info *task,
|
||||||
SFCommonTaskContext *ctx)
|
SFCommonTaskContext *ctx)
|
||||||
|
|
@ -307,180 +254,58 @@ static inline void sf_proto_init_task_context(struct fast_task_info *task,
|
||||||
ctx->response.header.cmd = SF_PROTO_ACK;
|
ctx->response.header.cmd = SF_PROTO_ACK;
|
||||||
ctx->response.header.body_len = 0;
|
ctx->response.header.body_len = 0;
|
||||||
ctx->response.header.status = 0;
|
ctx->response.header.status = 0;
|
||||||
ctx->response.header.flags = 0;
|
|
||||||
ctx->response.error.length = 0;
|
ctx->response.error.length = 0;
|
||||||
ctx->response.error.message[0] = '\0';
|
ctx->response.error.message[0] = '\0';
|
||||||
ctx->log_level = LOG_ERR;
|
ctx->log_level = LOG_ERR;
|
||||||
ctx->response_done = false;
|
ctx->response_done = false;
|
||||||
ctx->need_response = true;
|
ctx->need_response = true;
|
||||||
|
|
||||||
ctx->request.header.cmd = ((SFCommonProtoHeader *)
|
ctx->request.header.cmd = ((SFCommonProtoHeader *)task->data)->cmd;
|
||||||
task->recv.ptr->data)->cmd;
|
ctx->request.header.body_len = task->length - sizeof(SFCommonProtoHeader);
|
||||||
ctx->request.header.body_len = SF_RECV_BODY_LENGTH(task);
|
|
||||||
ctx->request.header.status = buff2short(((SFCommonProtoHeader *)
|
ctx->request.header.status = buff2short(((SFCommonProtoHeader *)
|
||||||
task->recv.ptr->data)->status);
|
task->data)->status);
|
||||||
ctx->request.header.flags = buff2short(((SFCommonProtoHeader *)
|
ctx->request.body = task->data + sizeof(SFCommonProtoHeader);
|
||||||
task->recv.ptr->data)->flags);
|
|
||||||
if (task->recv_body != NULL) {
|
|
||||||
ctx->request.body = task->recv_body;
|
|
||||||
} else {
|
|
||||||
ctx->request.body = SF_PROTO_RECV_BODY(task);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* task send and recv buffer operations */
|
|
||||||
static inline int sf_set_task_send_buffer_size(
|
|
||||||
struct fast_task_info *task, const int expect_size)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_set_buffer_size(task, task->send.ptr,
|
|
||||||
expect_size)) == 0)
|
|
||||||
{
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->send.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_set_task_recv_buffer_size(
|
|
||||||
struct fast_task_info *task, const int expect_size)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_set_buffer_size(task, task->recv.ptr,
|
|
||||||
expect_size)) == 0)
|
|
||||||
{
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->recv.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_set_task_send_max_buffer_size(
|
|
||||||
struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_set_max_buffer_size(task, task->send.ptr)) == 0) {
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->send.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_set_task_recv_max_buffer_size(
|
|
||||||
struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_set_max_buffer_size(task, task->recv.ptr)) == 0) {
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->recv.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_realloc_task_send_buffer(
|
|
||||||
struct fast_task_info *task, const int expect_size)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_realloc_buffer(task, task->send.ptr,
|
|
||||||
expect_size)) == 0)
|
|
||||||
{
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->send.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_realloc_task_recv_buffer(
|
|
||||||
struct fast_task_info *task, const int expect_size)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_realloc_buffer(task, task->recv.ptr,
|
|
||||||
expect_size)) == 0)
|
|
||||||
{
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->recv.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_realloc_task_send_max_buffer(
|
|
||||||
struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_realloc_max_buffer(task, task->send.ptr)) == 0) {
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->send.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_realloc_task_recv_max_buffer(
|
|
||||||
struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
if ((result=free_queue_realloc_max_buffer(task, task->recv.ptr)) == 0) {
|
|
||||||
SF_PROTO_SET_MAGIC(((SFCommonProtoHeader *)
|
|
||||||
task->recv.ptr->data)->magic);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline void sf_log_network_error_ex1(SFResponseInfo *response,
|
static inline void sf_log_network_error_ex1(SFResponseInfo *response,
|
||||||
const ConnectionInfo *conn, const char *service_name,
|
const ConnectionInfo *conn, const int result,
|
||||||
const int result, const int log_level,
|
const int log_level, const char *file, const int line)
|
||||||
const char *file, const int line)
|
|
||||||
{
|
{
|
||||||
if (response->error.length > 0) {
|
if (response->error.length > 0) {
|
||||||
log_it_ex(&g_log_context, log_level, "file: %s, line: %d, "
|
log_it_ex(&g_log_context, log_level,
|
||||||
"%s%sserver %s:%u response message: %s", file, line,
|
"file: %s, line: %d, "
|
||||||
(service_name != NULL ? service_name : ""),
|
"server %s:%u response message: %s",
|
||||||
(service_name != NULL ? " ": ""),
|
file, line, conn->ip_addr, conn->port,
|
||||||
conn->ip_addr, conn->port,
|
|
||||||
response->error.message);
|
response->error.message);
|
||||||
} else {
|
} else {
|
||||||
log_it_ex(&g_log_context, log_level, "file: %s, line: %d, "
|
log_it_ex(&g_log_context, log_level,
|
||||||
"communicate with %s%sserver %s:%u fail, "
|
"file: %s, line: %d, "
|
||||||
|
"communicate with server %s:%u fail, "
|
||||||
"errno: %d, error info: %s", file, line,
|
"errno: %d, error info: %s", file, line,
|
||||||
(service_name != NULL ? service_name : ""),
|
|
||||||
(service_name != NULL ? " ": ""),
|
|
||||||
conn->ip_addr, conn->port,
|
conn->ip_addr, conn->port,
|
||||||
result, STRERROR(result));
|
result, STRERROR(result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sf_log_network_error_ex(response, conn, \
|
#define sf_log_network_error_ex(response, conn, result, log_level) \
|
||||||
service_name, result, log_level) \
|
sf_log_network_error_ex1(response, conn, result, \
|
||||||
sf_log_network_error_ex1(response, conn, service_name, \
|
log_level, __FILE__, __LINE__)
|
||||||
result, log_level, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
#define sf_log_network_error(response, conn, service_name, result) \
|
#define sf_log_network_error(response, conn, result) \
|
||||||
sf_log_network_error_ex1(response, conn, service_name, result, \
|
sf_log_network_error_ex1(response, conn, result, \
|
||||||
LOG_ERR, __FILE__, __LINE__)
|
LOG_ERR, __FILE__, __LINE__)
|
||||||
|
|
||||||
#define sf_log_network_error_for_update_ex(response, conn, \
|
#define sf_log_network_error_for_update(response, conn, result) \
|
||||||
service_name, result, enoent_log_level, file, line) \
|
sf_log_network_error_ex(response, conn, result, \
|
||||||
sf_log_network_error_ex1(response, conn, service_name, result, \
|
(result == SF_RETRIABLE_ERROR_CHANNEL_INVALID) ? \
|
||||||
(result == SF_RETRIABLE_ERROR_CHANNEL_INVALID) ? \
|
LOG_DEBUG : LOG_ERR)
|
||||||
LOG_DEBUG : ((result == ENOENT || result == ENODATA) ? \
|
|
||||||
enoent_log_level : LOG_ERR), file, line)
|
|
||||||
|
|
||||||
#define sf_log_network_error_for_update(response, conn, service_name, result) \
|
#define sf_log_network_error_for_delete(response, \
|
||||||
sf_log_network_error_for_update_ex(response, conn, service_name, \
|
conn, result, enoent_log_level) \
|
||||||
result, LOG_ERR, __FILE__, __LINE__)
|
sf_log_network_error_ex(response, conn, result, \
|
||||||
|
|
||||||
#define sf_log_network_error_for_delete_ex(response, conn, \
|
|
||||||
service_name, result, enoent_log_level, file, line) \
|
|
||||||
sf_log_network_error_ex1(response, conn, service_name, result, \
|
|
||||||
(result == SF_RETRIABLE_ERROR_CHANNEL_INVALID) ? \
|
(result == SF_RETRIABLE_ERROR_CHANNEL_INVALID) ? \
|
||||||
LOG_DEBUG : ((result == ENOENT || result == ENODATA) ? \
|
LOG_DEBUG : ((result == ENOENT || result == ENODATA) ? \
|
||||||
enoent_log_level : LOG_ERR), file, line)
|
enoent_log_level : LOG_ERR))
|
||||||
|
|
||||||
#define sf_log_network_error_for_delete(response, \
|
|
||||||
conn, service_name, result, enoent_log_level) \
|
|
||||||
sf_log_network_error_for_delete_ex(response, conn, service_name, \
|
|
||||||
result, enoent_log_level, __FILE__, __LINE__)
|
|
||||||
|
|
||||||
|
|
||||||
static inline int sf_server_expect_body_length(SFResponseInfo *response,
|
static inline int sf_server_expect_body_length(SFResponseInfo *response,
|
||||||
const int body_length, const int expect_body_len)
|
const int body_length, const int expect_body_len)
|
||||||
|
|
@ -562,16 +387,6 @@ int sf_recv_response(ConnectionInfo *conn, SFResponseInfo *response,
|
||||||
const int network_timeout, const unsigned char expect_cmd,
|
const int network_timeout, const unsigned char expect_cmd,
|
||||||
char *recv_data, const int expect_body_len);
|
char *recv_data, const int expect_body_len);
|
||||||
|
|
||||||
static inline int sf_recv_none_body_response(ConnectionInfo *conn,
|
|
||||||
SFResponseInfo *response, const int network_timeout,
|
|
||||||
const unsigned char expect_cmd)
|
|
||||||
{
|
|
||||||
char *recv_data = NULL;
|
|
||||||
const int expect_body_len = 0;
|
|
||||||
return sf_recv_response(conn, response, network_timeout,
|
|
||||||
expect_cmd, recv_data, expect_body_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_recv_vary_response(ConnectionInfo *conn, SFResponseInfo *response,
|
int sf_recv_vary_response(ConnectionInfo *conn, SFResponseInfo *response,
|
||||||
const int network_timeout, const unsigned char expect_cmd,
|
const int network_timeout, const unsigned char expect_cmd,
|
||||||
SFProtoRecvBuffer *buffer, const int min_body_len);
|
SFProtoRecvBuffer *buffer, const int min_body_len);
|
||||||
|
|
@ -606,56 +421,6 @@ static inline void sf_free_recv_buffer(SFProtoRecvBuffer *buffer)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sf_proto_send_buf1(ConnectionInfo *conn, char *data,
|
|
||||||
const int len, SFResponseInfo *response, const int network_timeout)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
|
||||||
result = G_RDMA_CONNECTION_CALLBACKS.request_by_buf1(
|
|
||||||
conn, data, len, network_timeout * 1000);
|
|
||||||
} else {
|
|
||||||
result = tcpsenddata_nb(conn->sock, data, len, network_timeout);
|
|
||||||
}
|
|
||||||
if (result != 0) {
|
|
||||||
response->error.length = snprintf(response->error.message,
|
|
||||||
sizeof(response->error.message),
|
|
||||||
"send data fail, errno: %d, error info: %s",
|
|
||||||
result, STRERROR(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_proto_send_buf2(ConnectionInfo *conn, char *buff1,
|
|
||||||
const int length1, char *buff2, const int length2,
|
|
||||||
SFResponseInfo *response, const int network_timeout)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
|
|
||||||
if (conn->comm_type == fc_comm_type_rdma) {
|
|
||||||
result = G_RDMA_CONNECTION_CALLBACKS.request_by_buf2(
|
|
||||||
conn, buff1, length1, buff2, length2,
|
|
||||||
network_timeout * 1000);
|
|
||||||
} else {
|
|
||||||
if ((result=tcpsenddata_nb(conn->sock, buff1, length1,
|
|
||||||
network_timeout)) == 0)
|
|
||||||
{
|
|
||||||
result = tcpsenddata_nb(conn->sock, buff2, length2,
|
|
||||||
network_timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result != 0) {
|
|
||||||
response->error.length = snprintf(response->error.message,
|
|
||||||
sizeof(response->error.message),
|
|
||||||
"send data fail, errno: %d, error info: %s",
|
|
||||||
result, STRERROR(result));
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data,
|
int sf_send_and_recv_response_header(ConnectionInfo *conn, char *data,
|
||||||
const int len, SFResponseInfo *response, const int network_timeout);
|
const int len, SFResponseInfo *response, const int network_timeout);
|
||||||
|
|
||||||
|
|
@ -716,27 +481,16 @@ int sf_send_and_recv_vary_response(ConnectionInfo *conn,
|
||||||
const int network_timeout, const unsigned char expect_cmd,
|
const int network_timeout, const unsigned char expect_cmd,
|
||||||
SFProtoRecvBuffer *buffer, const int min_body_len);
|
SFProtoRecvBuffer *buffer, const int min_body_len);
|
||||||
|
|
||||||
static inline int sf_proto_parse_header(const SFCommonProtoHeader
|
static inline void sf_proto_extract_header(const SFCommonProtoHeader
|
||||||
*header_proto, SFResponseInfo *response)
|
*header_proto, SFHeaderInfo *header_info)
|
||||||
{
|
{
|
||||||
if (!SF_PROTO_CHECK_MAGIC(header_proto->magic)) {
|
header_info->cmd = header_proto->cmd;
|
||||||
response->error.length = snprintf(response->error.message,
|
header_info->body_len = buff2int(header_proto->body_len);
|
||||||
sizeof(response->error.message),
|
header_info->flags = buff2short(header_proto->flags);
|
||||||
"magic "SF_PROTO_MAGIC_FORMAT" is invalid, "
|
header_info->status = buff2short(header_proto->status);
|
||||||
"expect: "SF_PROTO_MAGIC_FORMAT,
|
if (header_info->status > 255) {
|
||||||
SF_PROTO_MAGIC_PARAMS(header_proto->magic),
|
header_info->status = sf_localize_errno(header_info->status);
|
||||||
SF_PROTO_MAGIC_EXPECT_PARAMS);
|
|
||||||
return EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
response->header.cmd = header_proto->cmd;
|
|
||||||
response->header.body_len = buff2int(header_proto->body_len);
|
|
||||||
response->header.flags = buff2short(header_proto->flags);
|
|
||||||
response->header.status = buff2short(header_proto->status);
|
|
||||||
if (response->header.status > 255) {
|
|
||||||
response->header.status = sf_localize_errno(response->header.status);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void sf_proto_pack_limit(const SFListLimitInfo
|
static inline void sf_proto_pack_limit(const SFListLimitInfo
|
||||||
|
|
@ -775,33 +529,16 @@ int sf_proto_deal_ack(struct fast_task_info *task,
|
||||||
SFRequestInfo *request, SFResponseInfo *response);
|
SFRequestInfo *request, SFResponseInfo *response);
|
||||||
|
|
||||||
int sf_proto_rebind_idempotency_channel(ConnectionInfo *conn,
|
int sf_proto_rebind_idempotency_channel(ConnectionInfo *conn,
|
||||||
const char *service_name, const uint32_t channel_id,
|
const uint32_t channel_id, const int key, const int network_timeout);
|
||||||
const int key, const int network_timeout);
|
|
||||||
|
|
||||||
int sf_proto_get_group_servers(ConnectionInfo *conn,
|
int sf_proto_get_group_servers(ConnectionInfo *conn,
|
||||||
const char *service_name, const int network_timeout,
|
const int network_timeout, const int group_id,
|
||||||
const int group_id, SFGroupServerArray *sarray);
|
SFGroupServerArray *sarray);
|
||||||
|
|
||||||
int sf_proto_get_leader(ConnectionInfo *conn, const char *service_name,
|
int sf_proto_get_leader(ConnectionInfo *conn,
|
||||||
const int network_timeout, SFClientServerEntry *leader);
|
const int network_timeout,
|
||||||
|
SFClientServerEntry *leader);
|
||||||
|
|
||||||
static inline void sf_proto_get_server_status_pack(
|
|
||||||
const SFGetServerStatusRequest *r,
|
|
||||||
SFProtoGetServerStatusReq *req)
|
|
||||||
{
|
|
||||||
int2buff(r->server_id, req->server_id);
|
|
||||||
req->is_leader = (r->is_leader ? 1 : 0);
|
|
||||||
req->auth_enabled = (r->auth_enabled ? 1 : 0);
|
|
||||||
memcpy(req->config_signs.servers, r->servers_sign,
|
|
||||||
SF_CLUSTER_CONFIG_SIGN_LEN);
|
|
||||||
if (r->cluster_sign != NULL) {
|
|
||||||
memcpy(req->config_signs.cluster, r->cluster_sign,
|
|
||||||
SF_CLUSTER_CONFIG_SIGN_LEN);
|
|
||||||
} else {
|
|
||||||
memset(req->config_signs.cluster, 0,
|
|
||||||
SF_CLUSTER_CONFIG_SIGN_LEN);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define SF_CLIENT_RELEASE_CONNECTION(cm, conn, result) \
|
#define SF_CLIENT_RELEASE_CONNECTION(cm, conn, result) \
|
||||||
do { \
|
do { \
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@
|
||||||
#include "fastcommon/common_define.h"
|
#include "fastcommon/common_define.h"
|
||||||
#include "fastcommon/shared_func.h"
|
#include "fastcommon/shared_func.h"
|
||||||
#include "fastcommon/fast_buffer.h"
|
#include "fastcommon/fast_buffer.h"
|
||||||
#include "fastcommon/uniq_skiplist.h"
|
|
||||||
#include "fastcommon/hash.h"
|
#include "fastcommon/hash.h"
|
||||||
|
|
||||||
#define SF_SERIALIZER_VALUE_TYPE_COUNT 12
|
#define SF_SERIALIZER_VALUE_TYPE_COUNT 12
|
||||||
|
|
@ -439,44 +438,6 @@ static inline int sf_serializer_pack_id_name_array(FastBuffer *buffer,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int sf_serializer_pack_id_name_skiplist(
|
|
||||||
FastBuffer *buffer, const unsigned char fid,
|
|
||||||
UniqSkiplist *sl)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
int length;
|
|
||||||
SFSerializerPackFieldArray *obj;
|
|
||||||
const id_name_pair_t *pair;
|
|
||||||
UniqSkiplistIterator it;
|
|
||||||
char *p;
|
|
||||||
|
|
||||||
length = sizeof(SFSerializerPackFieldArray);
|
|
||||||
uniq_skiplist_iterator(sl, &it);
|
|
||||||
while ((pair=uniq_skiplist_next(&it)) != NULL) {
|
|
||||||
length += sizeof(int64_t) + pair->name.len +
|
|
||||||
sizeof(SFSerializerPackStringValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result=fast_buffer_check_inc_size(buffer, length)) != 0) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = (SFSerializerPackFieldArray *)(buffer->data + buffer->length);
|
|
||||||
obj->field.id = fid;
|
|
||||||
obj->field.type = sf_serializer_value_type_id_name_array;
|
|
||||||
int2buff(uniq_skiplist_count(sl), obj->value.count);
|
|
||||||
|
|
||||||
p = obj->value.ptr;
|
|
||||||
uniq_skiplist_iterator(sl, &it);
|
|
||||||
while ((pair=uniq_skiplist_next(&it)) != NULL) {
|
|
||||||
long2buff(pair->id, p);
|
|
||||||
p += sizeof(int64_t);
|
|
||||||
SF_SERIALIZER_PACK_STRING_AND_MOVE_PTR(p, &pair->name);
|
|
||||||
}
|
|
||||||
buffer->length += length;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sf_serializer_pack_map(FastBuffer *buffer,
|
static inline int sf_serializer_pack_map(FastBuffer *buffer,
|
||||||
const unsigned char fid, const key_value_pair_t *kv_pairs,
|
const unsigned char fid, const key_value_pair_t *kv_pairs,
|
||||||
const int count)
|
const int count)
|
||||||
|
|
|
||||||
602
src/sf_service.c
602
src/sf_service.c
|
|
@ -25,7 +25,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ifaddrs.h>
|
|
||||||
#include "fastcommon/logger.h"
|
#include "fastcommon/logger.h"
|
||||||
#include "fastcommon/sockopt.h"
|
#include "fastcommon/sockopt.h"
|
||||||
#include "fastcommon/shared_func.h"
|
#include "fastcommon/shared_func.h"
|
||||||
|
|
@ -33,8 +32,9 @@
|
||||||
#include "fastcommon/sched_thread.h"
|
#include "fastcommon/sched_thread.h"
|
||||||
#include "fastcommon/ioevent_loop.h"
|
#include "fastcommon/ioevent_loop.h"
|
||||||
#include "fastcommon/fc_memory.h"
|
#include "fastcommon/fc_memory.h"
|
||||||
#include "sf_proto.h"
|
#include "sf_nio.h"
|
||||||
#include "sf_util.h"
|
#include "sf_util.h"
|
||||||
|
#include "sf_global.h"
|
||||||
#include "sf_service.h"
|
#include "sf_service.h"
|
||||||
|
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
|
|
@ -57,46 +57,62 @@ struct worker_thread_context {
|
||||||
struct nio_thread_data *thread_data;
|
struct nio_thread_data *thread_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct accept_thread_context {
|
||||||
|
SFContext *sf_context;
|
||||||
|
int server_sock;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int sf_init_task(struct fast_task_info *task)
|
||||||
|
{
|
||||||
|
task->connect_timeout = SF_G_CONNECT_TIMEOUT; //for client side
|
||||||
|
task->network_timeout = SF_G_NETWORK_TIMEOUT;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void *worker_thread_entrance(void *arg);
|
static void *worker_thread_entrance(void *arg);
|
||||||
|
|
||||||
static int sf_init_free_queue(SFContext *sf_context, const char *name,
|
static int sf_init_free_queues(const int task_arg_size,
|
||||||
const bool double_buffers, const bool need_shrink_task_buffer,
|
TaskInitCallback init_callback)
|
||||||
const int task_padding_size, const int task_arg_size,
|
|
||||||
TaskInitCallback init_callback, void *init_arg)
|
|
||||||
{
|
{
|
||||||
|
#define ALLOC_CONNECTIONS_ONCE 1024
|
||||||
|
|
||||||
|
static bool sf_inited = false;
|
||||||
int result;
|
int result;
|
||||||
int buffer_size;
|
|
||||||
int m;
|
int m;
|
||||||
int max_m;
|
int init_connections;
|
||||||
int alloc_conn_once;
|
int alloc_conn_once;
|
||||||
|
|
||||||
|
if (sf_inited) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sf_inited = true;
|
||||||
if ((result=set_rand_seed()) != 0) {
|
if ((result=set_rand_seed()) != 0) {
|
||||||
logCrit("file: "__FILE__", line: %d, "
|
logCrit("file: "__FILE__", line: %d, "
|
||||||
"set_rand_seed fail, program exit!", __LINE__);
|
"set_rand_seed fail, program exit!", __LINE__);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strcmp(name, "cluster") == 0 || strcmp(name, "replica") == 0) {
|
m = g_sf_global_vars.min_buff_size / (64 * 1024);
|
||||||
buffer_size = FC_MAX(4 * 1024 * 1024, sf_context->
|
|
||||||
net_buffer_cfg.max_buff_size);
|
|
||||||
max_m = 64;
|
|
||||||
} else {
|
|
||||||
buffer_size = sf_context->net_buffer_cfg.min_buff_size;
|
|
||||||
max_m = 16;
|
|
||||||
}
|
|
||||||
m = buffer_size / (64 * 1024);
|
|
||||||
if (m == 0) {
|
if (m == 0) {
|
||||||
m = 1;
|
m = 1;
|
||||||
} else if (m > max_m) {
|
} else if (m > 16) {
|
||||||
m = max_m;
|
m = 16;
|
||||||
|
}
|
||||||
|
alloc_conn_once = ALLOC_CONNECTIONS_ONCE / m;
|
||||||
|
init_connections = g_sf_global_vars.max_connections < alloc_conn_once ?
|
||||||
|
g_sf_global_vars.max_connections : alloc_conn_once;
|
||||||
|
if ((result=free_queue_init_ex2(g_sf_global_vars.max_connections,
|
||||||
|
init_connections, alloc_conn_once, g_sf_global_vars.
|
||||||
|
min_buff_size, g_sf_global_vars.max_buff_size,
|
||||||
|
task_arg_size, init_callback != NULL ?
|
||||||
|
init_callback : sf_init_task)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
alloc_conn_once = 256 / m;
|
|
||||||
|
|
||||||
return free_queue_init_ex2(&sf_context->free_queue, name, double_buffers,
|
return 0;
|
||||||
need_shrink_task_buffer, sf_context->net_buffer_cfg.max_connections,
|
|
||||||
alloc_conn_once, sf_context->net_buffer_cfg.min_buff_size,
|
|
||||||
sf_context->net_buffer_cfg.max_buff_size, task_padding_size,
|
|
||||||
task_arg_size, init_callback, init_arg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
|
|
@ -105,21 +121,14 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
ThreadLoopCallback thread_loop_callback,
|
ThreadLoopCallback thread_loop_callback,
|
||||||
sf_accept_done_callback accept_done_callback,
|
sf_accept_done_callback accept_done_callback,
|
||||||
sf_set_body_length_callback set_body_length_func,
|
sf_set_body_length_callback set_body_length_func,
|
||||||
sf_alloc_recv_buffer_callback alloc_recv_buffer_func,
|
sf_deal_task_func deal_func, TaskCleanUpCallback task_cleanup_func,
|
||||||
sf_send_done_callback send_done_callback,
|
|
||||||
sf_deal_task_callback deal_func, TaskCleanUpCallback task_cleanup_func,
|
|
||||||
sf_recv_timeout_callback timeout_callback, const int net_timeout_ms,
|
sf_recv_timeout_callback timeout_callback, const int net_timeout_ms,
|
||||||
const int proto_header_size, const int task_padding_size,
|
const int proto_header_size, const int task_arg_size,
|
||||||
const int task_arg_size, const bool double_buffers,
|
TaskInitCallback init_callback, sf_release_buffer_callback
|
||||||
const bool need_shrink_task_buffer, const bool explicit_post_recv,
|
release_buffer_callback)
|
||||||
TaskInitCallback init_callback, void *init_arg,
|
|
||||||
sf_release_buffer_callback release_buffer_callback)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int bytes;
|
int bytes;
|
||||||
int extra_events;
|
|
||||||
int max_entries;
|
|
||||||
int i;
|
|
||||||
struct worker_thread_context *thread_contexts;
|
struct worker_thread_context *thread_contexts;
|
||||||
struct worker_thread_context *thread_ctx;
|
struct worker_thread_context *thread_ctx;
|
||||||
struct nio_thread_data *thread_data;
|
struct nio_thread_data *thread_data;
|
||||||
|
|
@ -127,26 +136,15 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
pthread_attr_t thread_attr;
|
pthread_attr_t thread_attr;
|
||||||
|
|
||||||
fc_safe_strcpy(sf_context->name, name);
|
snprintf(sf_context->name, sizeof(sf_context->name), "%s", name);
|
||||||
sf_context->connect_need_log = true;
|
sf_context->realloc_task_buffer = g_sf_global_vars.
|
||||||
sf_context->realloc_task_buffer = sf_context->net_buffer_cfg.
|
min_buff_size < g_sf_global_vars.max_buff_size;
|
||||||
min_buff_size < sf_context->net_buffer_cfg.max_buff_size;
|
sf_context->accept_done_func = accept_done_callback;
|
||||||
sf_context->callbacks.accept_done = accept_done_callback;
|
|
||||||
sf_set_parameters_ex(sf_context, proto_header_size,
|
sf_set_parameters_ex(sf_context, proto_header_size,
|
||||||
set_body_length_func, alloc_recv_buffer_func,
|
set_body_length_func, deal_func, task_cleanup_func,
|
||||||
send_done_callback, deal_func, task_cleanup_func,
|
|
||||||
timeout_callback, release_buffer_callback);
|
timeout_callback, release_buffer_callback);
|
||||||
if (explicit_post_recv) {
|
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
|
||||||
sf_context->handlers[i].handlers[SF_RDMACM_NETWORK_HANDLER_INDEX].
|
|
||||||
explicit_post_recv = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result=sf_init_free_queue(sf_context, name, double_buffers,
|
if ((result=sf_init_free_queues(task_arg_size, init_callback)) != 0) {
|
||||||
need_shrink_task_buffer, task_padding_size,
|
|
||||||
task_arg_size, init_callback, init_arg)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -171,71 +169,12 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SF_G_EPOLL_EDGE_TRIGGER) {
|
|
||||||
#ifdef OS_LINUX
|
|
||||||
#if IOEVENT_USE_EPOLL
|
|
||||||
extra_events = EPOLLET;
|
|
||||||
#else
|
|
||||||
extra_events = 0;
|
|
||||||
#endif
|
|
||||||
#elif defined(OS_FREEBSD)
|
|
||||||
extra_events = EV_CLEAR;
|
|
||||||
#else
|
|
||||||
extra_events = 0;
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
extra_events = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
max_entries = (sf_context->net_buffer_cfg.max_connections +
|
|
||||||
sf_context->work_threads - 1) / sf_context->work_threads;
|
|
||||||
if (strcmp(sf_context->name, "cluster") == 0 ||
|
|
||||||
strcmp(sf_context->name, "replica") == 0)
|
|
||||||
{
|
|
||||||
if (max_entries < 1024) {
|
|
||||||
max_entries += 8;
|
|
||||||
} else {
|
|
||||||
max_entries = 1024;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (max_entries < 4 * 1024) {
|
|
||||||
max_entries = max_entries * 2;
|
|
||||||
} else if (max_entries < 8 * 1024) {
|
|
||||||
max_entries = (max_entries * 3) / 2;
|
|
||||||
} else if (max_entries < 16 * 1024) {
|
|
||||||
max_entries = (max_entries * 5) / 4;
|
|
||||||
} else if (max_entries < 32 * 1024) {
|
|
||||||
max_entries = (max_entries * 6) / 5;
|
|
||||||
} else if (max_entries < 64 * 1024) {
|
|
||||||
max_entries = (max_entries * 11) / 10;
|
|
||||||
} else if (max_entries < 128 * 1024) {
|
|
||||||
max_entries = (max_entries * 21) / 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
if (sf_context->use_io_uring) {
|
|
||||||
if (max_entries > 32 * 1024) {
|
|
||||||
max_entries = 32 * 1024;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
g_current_time = time(NULL);
|
g_current_time = time(NULL);
|
||||||
sf_context->thread_count = 0;
|
sf_context->thread_count = 0;
|
||||||
data_end = sf_context->thread_data + sf_context->work_threads;
|
data_end = sf_context->thread_data + sf_context->work_threads;
|
||||||
for (thread_data=sf_context->thread_data,thread_ctx=thread_contexts;
|
for (thread_data=sf_context->thread_data,thread_ctx=thread_contexts;
|
||||||
thread_data<data_end; thread_data++,thread_ctx++)
|
thread_data<data_end; thread_data++,thread_ctx++)
|
||||||
{
|
{
|
||||||
thread_data->timeout_ms = net_timeout_ms;
|
|
||||||
FC_INIT_LIST_HEAD(&thread_data->polling_queue);
|
|
||||||
if (sf_context->smart_polling.enabled) {
|
|
||||||
thread_data->busy_polling_callback =
|
|
||||||
sf_rdma_busy_polling_callback;
|
|
||||||
} else {
|
|
||||||
thread_data->busy_polling_callback = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
thread_data->thread_loop_callback = thread_loop_callback;
|
thread_data->thread_loop_callback = thread_loop_callback;
|
||||||
if (alloc_thread_extra_data_callback != NULL) {
|
if (alloc_thread_extra_data_callback != NULL) {
|
||||||
thread_data->arg = alloc_thread_extra_data_callback(
|
thread_data->arg = alloc_thread_extra_data_callback(
|
||||||
|
|
@ -245,45 +184,19 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
thread_data->arg = NULL;
|
thread_data->arg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=ioevent_init(&thread_data->ev_puller, sf_context->
|
if (ioevent_init(&thread_data->ev_puller,
|
||||||
name, sf_context->use_io_uring, max_entries,
|
g_sf_global_vars.max_connections + 2, net_timeout_ms, 0) != 0)
|
||||||
net_timeout_ms, extra_events)) != 0)
|
|
||||||
{
|
{
|
||||||
char prompt[256];
|
result = errno != 0 ? errno : ENOMEM;
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
if (sf_context->use_io_uring) {
|
|
||||||
if (result == EPERM) {
|
|
||||||
strcpy(prompt, " make sure kernel."
|
|
||||||
"io_uring_disabled set to 0");
|
|
||||||
} else if (result == EINVAL) {
|
|
||||||
sprintf(prompt, " maybe max_connections: %d is too large"
|
|
||||||
" or [%s]'s work_threads: %d is too small",
|
|
||||||
sf_context->net_buffer_cfg.max_connections,
|
|
||||||
sf_context->name, sf_context->work_threads);
|
|
||||||
} else {
|
|
||||||
*prompt = '\0';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
#endif
|
|
||||||
*prompt = '\0';
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"ioevent_init fail, errno: %d, error info: %s.%s"
|
"ioevent_init fail, "
|
||||||
, __LINE__, result, strerror(result), prompt);
|
"errno: %d, error info: %s",
|
||||||
|
__LINE__, result, strerror(result));
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if IOEVENT_USE_URING
|
result = fast_timer_init(&thread_data->timer,
|
||||||
if (sf_context->use_io_uring && send_done_callback != NULL) {
|
2 * g_sf_global_vars.network_timeout, g_current_time);
|
||||||
ioevent_set_send_zc_done_notify(&thread_data->ev_puller, true);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
result = fast_timer_init(&thread_data->timer, 2 * sf_context->
|
|
||||||
net_buffer_cfg.network_timeout, g_current_time);
|
|
||||||
if (result != 0) {
|
if (result != 0) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"fast_timer_init fail, errno: %d, error info: %s",
|
"fast_timer_init fail, errno: %d, error info: %s",
|
||||||
|
|
@ -291,14 +204,11 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=init_pthread_lock(&thread_data->
|
if ((result=init_pthread_lock(&thread_data->waiting_queue.lock)) != 0) {
|
||||||
waiting_queue.lock)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
#if defined(OS_LINUX)
|
#if defined(OS_LINUX)
|
||||||
FC_NOTIFY_READ_FD(thread_data) = eventfd(0,
|
FC_NOTIFY_READ_FD(thread_data) = eventfd(0, EFD_NONBLOCK);
|
||||||
EFD_NONBLOCK | EFD_CLOEXEC);
|
|
||||||
if (FC_NOTIFY_READ_FD(thread_data) < 0) {
|
if (FC_NOTIFY_READ_FD(thread_data) < 0) {
|
||||||
result = errno != 0 ? errno : EPERM;
|
result = errno != 0 ? errno : EPERM;
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
|
@ -322,8 +232,6 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
FC_SET_CLOEXEC(FC_NOTIFY_READ_FD(thread_data));
|
|
||||||
FC_SET_CLOEXEC(FC_NOTIFY_WRITE_FD(thread_data));
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
thread_ctx->sf_context = sf_context;
|
thread_ctx->sf_context = sf_context;
|
||||||
|
|
@ -348,7 +256,7 @@ int sf_service_destroy_ex(SFContext *sf_context)
|
||||||
{
|
{
|
||||||
struct nio_thread_data *data_end, *thread_data;
|
struct nio_thread_data *data_end, *thread_data;
|
||||||
|
|
||||||
free_queue_destroy(&sf_context->free_queue);
|
free_queue_destroy();
|
||||||
data_end = sf_context->thread_data + sf_context->work_threads;
|
data_end = sf_context->thread_data + sf_context->work_threads;
|
||||||
for (thread_data=sf_context->thread_data; thread_data<data_end;
|
for (thread_data=sf_context->thread_data; thread_data<data_end;
|
||||||
thread_data++)
|
thread_data++)
|
||||||
|
|
@ -401,7 +309,7 @@ static void *worker_thread_entrance(void *arg)
|
||||||
|
|
||||||
ioevent_loop(thread_ctx->thread_data,
|
ioevent_loop(thread_ctx->thread_data,
|
||||||
sf_recv_notify_read,
|
sf_recv_notify_read,
|
||||||
thread_ctx->sf_context->callbacks.task_cleanup,
|
thread_ctx->sf_context->task_cleanup_func,
|
||||||
&g_sf_global_vars.continue_flag);
|
&g_sf_global_vars.continue_flag);
|
||||||
ioevent_destroy(&thread_ctx->thread_data->ev_puller);
|
ioevent_destroy(&thread_ctx->thread_data->ev_puller);
|
||||||
|
|
||||||
|
|
@ -416,20 +324,15 @@ static void *worker_thread_entrance(void *arg)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_socket_create_server(SFListener *listener,
|
static int _socket_server(const char *bind_addr, int port, int *sock)
|
||||||
int af, const char *bind_addr)
|
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
|
*sock = socketServer(bind_addr, port, &result);
|
||||||
listener->sock = socketServer2(af, bind_addr,
|
if (*sock < 0) {
|
||||||
listener->port, &result);
|
|
||||||
if (listener->sock < 0) {
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=tcpsetserveropt(listener->sock, listener->handler->
|
if ((result=tcpsetserveropt(*sock, g_sf_global_vars.network_timeout)) != 0) {
|
||||||
fh->ctx->net_buffer_cfg.network_timeout)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -439,215 +342,113 @@ int sf_socket_create_server(SFListener *listener,
|
||||||
int sf_socket_server_ex(SFContext *sf_context)
|
int sf_socket_server_ex(SFContext *sf_context)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
int i;
|
|
||||||
bool dual_ports;
|
|
||||||
const char *bind_addr;
|
const char *bind_addr;
|
||||||
SFAddressFamilyHandler *fh;
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
SFNetworkHandler *end;
|
|
||||||
|
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
sf_context->inner_sock = sf_context->outer_sock = -1;
|
||||||
fh = sf_context->handlers + i;
|
if (sf_context->outer_port == sf_context->inner_port) {
|
||||||
if (fh->af == AF_UNSPEC) {
|
if (*sf_context->outer_bind_addr == '\0' ||
|
||||||
continue;
|
*sf_context->inner_bind_addr == '\0') {
|
||||||
}
|
bind_addr = "";
|
||||||
|
return _socket_server(bind_addr, sf_context->outer_port,
|
||||||
end = fh->handlers + SF_NETWORK_HANDLER_COUNT;
|
&sf_context->outer_sock);
|
||||||
for (handler=fh->handlers; handler<end; handler++) {
|
} else if (strcmp(sf_context->outer_bind_addr,
|
||||||
if (!handler->enabled) {
|
sf_context->inner_bind_addr) == 0) {
|
||||||
continue;
|
bind_addr = sf_context->outer_bind_addr;
|
||||||
}
|
if (is_private_ip(bind_addr)) {
|
||||||
|
return _socket_server(bind_addr, sf_context->
|
||||||
handler->inner.enabled = false;
|
inner_port, &sf_context->inner_sock);
|
||||||
handler->outer.enabled = false;
|
|
||||||
if (handler->outer.port == handler->inner.port) {
|
|
||||||
if (*fh->outer_bind_addr == '\0' ||
|
|
||||||
*fh->inner_bind_addr == '\0')
|
|
||||||
{
|
|
||||||
bind_addr = "";
|
|
||||||
if ((result=handler->create_server(&handler->
|
|
||||||
outer, fh->af, bind_addr)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
handler->outer.enabled = true;
|
|
||||||
dual_ports = false;
|
|
||||||
} else if (strcmp(fh->outer_bind_addr,
|
|
||||||
fh->inner_bind_addr) == 0)
|
|
||||||
{
|
|
||||||
bind_addr = fh->outer_bind_addr;
|
|
||||||
if (is_private_ip(bind_addr)) {
|
|
||||||
if ((result=handler->create_server(&handler->
|
|
||||||
inner, fh->af, bind_addr)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
handler->inner.enabled = true;
|
|
||||||
} else {
|
|
||||||
if ((result=handler->create_server(&handler->
|
|
||||||
outer, fh->af, bind_addr)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
handler->outer.enabled = true;
|
|
||||||
}
|
|
||||||
dual_ports = false;
|
|
||||||
} else {
|
|
||||||
dual_ports = true;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
dual_ports = true;
|
return _socket_server(bind_addr, sf_context->
|
||||||
|
outer_port, &sf_context->outer_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dual_ports) {
|
|
||||||
if ((result=handler->create_server(&handler->outer,
|
|
||||||
fh->af, fh->outer_bind_addr)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((result=handler->create_server(&handler->inner,
|
|
||||||
fh->af, fh->inner_bind_addr)) != 0)
|
|
||||||
{
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
handler->inner.enabled = true;
|
|
||||||
handler->outer.enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
logInfo("%p [%d] inner {port: %d, enabled: %d}, "
|
|
||||||
"outer {port: %d, enabled: %d}", sf_context,
|
|
||||||
(int)(handler-sf_context->handlers),
|
|
||||||
handler->inner.port, handler->inner.enabled,
|
|
||||||
handler->outer.port, handler->outer.enabled);
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((result=_socket_server(sf_context->outer_bind_addr,
|
||||||
|
sf_context->outer_port, &sf_context->outer_sock)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((result=_socket_server(sf_context->inner_bind_addr,
|
||||||
|
sf_context->inner_port, &sf_context->inner_sock)) != 0)
|
||||||
|
{
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void sf_socket_close_server(SFListener *listener)
|
static void accept_run(struct accept_thread_context *accept_context)
|
||||||
{
|
|
||||||
if (listener->sock >= 0) {
|
|
||||||
close(listener->sock);
|
|
||||||
listener->sock = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct fast_task_info *sf_socket_accept_connection(SFListener *listener)
|
|
||||||
{
|
{
|
||||||
int incomesock;
|
int incomesock;
|
||||||
int port;
|
int port;
|
||||||
|
struct sockaddr_in inaddr;
|
||||||
socklen_t sockaddr_len;
|
socklen_t sockaddr_len;
|
||||||
struct fast_task_info *task;
|
struct fast_task_info *task;
|
||||||
|
|
||||||
sockaddr_len = sizeof(listener->inaddr);
|
|
||||||
incomesock = accept(listener->sock, (struct sockaddr *)
|
|
||||||
&listener->inaddr, &sockaddr_len);
|
|
||||||
if (incomesock < 0) { //error
|
|
||||||
if (!(errno == EINTR || errno == EAGAIN)) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"accept fail, errno: %d, error info: %s",
|
|
||||||
__LINE__, errno, strerror(errno));
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tcpsetnonblockopt(incomesock) != 0) {
|
|
||||||
close(incomesock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
FC_SET_CLOEXEC(incomesock);
|
|
||||||
|
|
||||||
if ((task=sf_alloc_init_server_task(listener->handler,
|
|
||||||
incomesock)) == NULL)
|
|
||||||
{
|
|
||||||
close(incomesock);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
getPeerIpAddPort(incomesock, task->client_ip,
|
|
||||||
sizeof(task->client_ip), &port);
|
|
||||||
task->port = port;
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_socket_close_ex(SFContext *sf_context)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
SFNetworkHandler *end;
|
|
||||||
|
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
|
||||||
if (sf_context->handlers[i].af == AF_UNSPEC) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
end = sf_context->handlers[i].handlers + SF_NETWORK_HANDLER_COUNT;
|
|
||||||
for (handler=sf_context->handlers[i].handlers; handler<end; handler++) {
|
|
||||||
if (!handler->enabled) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler->outer.enabled) {
|
|
||||||
handler->close_server(&handler->outer);
|
|
||||||
}
|
|
||||||
if (handler->inner.enabled) {
|
|
||||||
handler->close_server(&handler->inner);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void accept_run(SFListener *listener)
|
|
||||||
{
|
|
||||||
struct fast_task_info *task;
|
|
||||||
|
|
||||||
while (g_sf_global_vars.continue_flag) {
|
while (g_sf_global_vars.continue_flag) {
|
||||||
if ((task=listener->handler->accept_connection(listener)) == NULL) {
|
sockaddr_len = sizeof(inaddr);
|
||||||
|
incomesock = accept(accept_context->server_sock,
|
||||||
|
(struct sockaddr*)&inaddr, &sockaddr_len);
|
||||||
|
if (incomesock < 0) { //error
|
||||||
|
if (!(errno == EINTR || errno == EAGAIN)) {
|
||||||
|
logError("file: "__FILE__", line: %d, "
|
||||||
|
"accept fail, errno: %d, error info: %s",
|
||||||
|
__LINE__, errno, strerror(errno));
|
||||||
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
task->thread_data = listener->handler->fh->ctx->thread_data +
|
if (tcpsetnonblockopt(incomesock) != 0) {
|
||||||
task->event.fd % listener->handler->fh->ctx->work_threads;
|
close(incomesock);
|
||||||
if (listener->handler->fh->ctx->callbacks.accept_done != NULL) {
|
continue;
|
||||||
if (listener->handler->fh->ctx->callbacks.accept_done(task,
|
}
|
||||||
listener->inaddr.sin_addr.s_addr,
|
|
||||||
listener->is_inner) != 0)
|
if ((task=sf_alloc_init_task(accept_context->
|
||||||
{
|
sf_context, incomesock)) == NULL)
|
||||||
listener->handler->close_connection(task);
|
{
|
||||||
sf_release_task(task);
|
close(incomesock);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPeerIpAddPort(incomesock, task->client_ip,
|
||||||
|
sizeof(task->client_ip), &port);
|
||||||
|
task->port = port;
|
||||||
|
task->thread_data = accept_context->sf_context->thread_data +
|
||||||
|
incomesock % accept_context->sf_context->work_threads;
|
||||||
|
if (accept_context->sf_context->accept_done_func != NULL) {
|
||||||
|
accept_context->sf_context->accept_done_func(task,
|
||||||
|
accept_context->server_sock ==
|
||||||
|
accept_context->sf_context->inner_sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sf_nio_notify(task, SF_NIO_STAGE_INIT) != 0) {
|
if (sf_nio_notify(task, SF_NIO_STAGE_INIT) != 0) {
|
||||||
listener->handler->close_connection(task);
|
close(incomesock);
|
||||||
sf_release_task(task);
|
sf_release_task(task);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *accept_thread_entrance(SFListener *listener)
|
static void *accept_thread_entrance(struct accept_thread_context
|
||||||
|
*accept_context)
|
||||||
{
|
{
|
||||||
#ifdef OS_LINUX
|
#ifdef OS_LINUX
|
||||||
{
|
{
|
||||||
char thread_name[32];
|
char thread_name[32];
|
||||||
snprintf(thread_name, sizeof(thread_name), "%s-%s-listen",
|
snprintf(thread_name, sizeof(thread_name), "%s-listen",
|
||||||
listener->handler->comm_type == fc_comm_type_sock ?
|
accept_context->sf_context->name);
|
||||||
"sock" : "rdma", listener->handler->fh->ctx->name);
|
|
||||||
prctl(PR_SET_NAME, thread_name);
|
prctl(PR_SET_NAME, thread_name);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
accept_run(listener);
|
accept_run(accept_context);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _accept_loop(SFListener *listener, const int accept_threads)
|
void _accept_loop(struct accept_thread_context *accept_context,
|
||||||
|
const int accept_threads)
|
||||||
{
|
{
|
||||||
pthread_t tid;
|
pthread_t tid;
|
||||||
pthread_attr_t thread_attr;
|
pthread_attr_t thread_attr;
|
||||||
|
|
@ -655,7 +456,7 @@ int _accept_loop(SFListener *listener, const int accept_threads)
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (accept_threads <= 0) {
|
if (accept_threads <= 0) {
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((result=init_pthread_attr(&thread_attr, g_sf_global_vars.
|
if ((result=init_pthread_attr(&thread_attr, g_sf_global_vars.
|
||||||
|
|
@ -663,83 +464,68 @@ int _accept_loop(SFListener *listener, const int accept_threads)
|
||||||
{
|
{
|
||||||
logWarning("file: "__FILE__", line: %d, "
|
logWarning("file: "__FILE__", line: %d, "
|
||||||
"init_pthread_attr fail!", __LINE__);
|
"init_pthread_attr fail!", __LINE__);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
for (i=0; i<accept_threads; i++) {
|
for (i=0; i<accept_threads; i++) {
|
||||||
if ((result=pthread_create(&tid, &thread_attr,
|
if ((result=pthread_create(&tid, &thread_attr,
|
||||||
(void * (*)(void *))accept_thread_entrance,
|
(void * (*)(void *))accept_thread_entrance,
|
||||||
listener)) != 0)
|
accept_context)) != 0)
|
||||||
{
|
{
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"create thread failed, startup threads: %d, "
|
"create thread failed, startup threads: %d, "
|
||||||
"errno: %d, error info: %s",
|
"errno: %d, error info: %s",
|
||||||
__LINE__, i, result, strerror(result));
|
__LINE__, i, result, strerror(result));
|
||||||
return result;
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
pthread_attr_destroy(&thread_attr);
|
pthread_attr_destroy(&thread_attr);
|
||||||
return 0;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_accept_loop_ex(SFContext *sf_context, const bool blocked)
|
void sf_accept_loop_ex(SFContext *sf_context, const bool block)
|
||||||
{
|
{
|
||||||
int i;
|
struct accept_thread_context *accept_contexts;
|
||||||
SFNetworkHandler *handler;
|
int count;
|
||||||
SFNetworkHandler *hend;
|
int bytes;
|
||||||
SFListener *listeners[SF_ADDRESS_FAMILY_COUNT *
|
|
||||||
SF_NETWORK_HANDLER_COUNT * 2];
|
|
||||||
SFListener **listener;
|
|
||||||
SFListener **last;
|
|
||||||
SFListener **lend;
|
|
||||||
|
|
||||||
listener = listeners;
|
if (sf_context->outer_sock >= 0) {
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
count = 2;
|
||||||
if (sf_context->handlers[i].af == AF_UNSPEC) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
hend = sf_context->handlers[i].handlers + SF_NETWORK_HANDLER_COUNT;
|
|
||||||
for (handler=sf_context->handlers[i].handlers;
|
|
||||||
handler<hend; handler++)
|
|
||||||
{
|
|
||||||
if (!handler->enabled) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (handler->inner.enabled) {
|
|
||||||
*listener++ = &handler->inner;
|
|
||||||
}
|
|
||||||
if (handler->outer.enabled) {
|
|
||||||
*listener++ = &handler->outer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (listener == listeners) {
|
|
||||||
logError("file: "__FILE__", line: %d, "
|
|
||||||
"no listener!", __LINE__);
|
|
||||||
return ENOENT;
|
|
||||||
}
|
|
||||||
|
|
||||||
last = listener - 1;
|
|
||||||
if (blocked) {
|
|
||||||
lend = listener - 1;
|
|
||||||
} else {
|
} else {
|
||||||
lend = listener;
|
count = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (listener=listeners; listener<lend; listener++) {
|
bytes = sizeof(struct accept_thread_context) * count;
|
||||||
_accept_loop(*listener, sf_context->accept_threads);
|
accept_contexts = (struct accept_thread_context *)fc_malloc(bytes);
|
||||||
|
if (accept_contexts == NULL) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (blocked) {
|
accept_contexts[0].sf_context = sf_context;
|
||||||
_accept_loop(*last, sf_context->accept_threads - 1);
|
accept_contexts[0].server_sock = sf_context->inner_sock;
|
||||||
accept_run(*last);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
if (sf_context->outer_sock >= 0) {
|
||||||
|
accept_contexts[1].sf_context = sf_context;
|
||||||
|
accept_contexts[1].server_sock = sf_context->outer_sock;
|
||||||
|
|
||||||
|
if (sf_context->inner_sock >= 0) {
|
||||||
|
_accept_loop(accept_contexts, sf_context->accept_threads);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (block) {
|
||||||
|
_accept_loop(accept_contexts + 1, sf_context->accept_threads - 1);
|
||||||
|
accept_run(accept_contexts + 1);
|
||||||
|
} else {
|
||||||
|
_accept_loop(accept_contexts + 1, sf_context->accept_threads);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (block) {
|
||||||
|
_accept_loop(accept_contexts, sf_context->accept_threads - 1);
|
||||||
|
accept_run(accept_contexts);
|
||||||
|
} else {
|
||||||
|
_accept_loop(accept_contexts, sf_context->accept_threads);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_FLAG)
|
#if defined(DEBUG_FLAG)
|
||||||
|
|
@ -853,13 +639,15 @@ int sf_setup_signal_handler()
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define LOG_SCHEDULE_ENTRIES_COUNT 3
|
||||||
|
|
||||||
int sf_startup_schedule(pthread_t *schedule_tid)
|
int sf_startup_schedule(pthread_t *schedule_tid)
|
||||||
{
|
{
|
||||||
ScheduleArray scheduleArray;
|
ScheduleArray scheduleArray;
|
||||||
ScheduleEntry scheduleEntries[SF_LOG_SCHEDULE_ENTRIES_COUNT];
|
ScheduleEntry scheduleEntries[LOG_SCHEDULE_ENTRIES_COUNT];
|
||||||
|
|
||||||
scheduleArray.entries = scheduleEntries;
|
scheduleArray.entries = scheduleEntries;
|
||||||
sf_logger_setup_schedule(&g_log_context, &g_sf_global_vars.error_log,
|
sf_setup_schedule(&g_log_context, &g_sf_global_vars.error_log,
|
||||||
&scheduleArray);
|
&scheduleArray);
|
||||||
return sched_start(&scheduleArray, schedule_tid,
|
return sched_start(&scheduleArray, schedule_tid,
|
||||||
g_sf_global_vars.thread_stack_size, (bool * volatile)
|
g_sf_global_vars.thread_stack_size, (bool * volatile)
|
||||||
|
|
@ -870,7 +658,7 @@ int sf_add_slow_log_schedule(SFSlowLogContext *slowlog_ctx)
|
||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
ScheduleArray scheduleArray;
|
ScheduleArray scheduleArray;
|
||||||
ScheduleEntry scheduleEntries[SF_LOG_SCHEDULE_ENTRIES_COUNT];
|
ScheduleEntry scheduleEntries[LOG_SCHEDULE_ENTRIES_COUNT];
|
||||||
|
|
||||||
if (!slowlog_ctx->cfg.enabled) {
|
if (!slowlog_ctx->cfg.enabled) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|
@ -883,8 +671,8 @@ int sf_add_slow_log_schedule(SFSlowLogContext *slowlog_ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
scheduleArray.entries = scheduleEntries;
|
scheduleArray.entries = scheduleEntries;
|
||||||
sf_logger_setup_schedule(&slowlog_ctx->ctx, &slowlog_ctx->
|
sf_setup_schedule(&slowlog_ctx->ctx, &slowlog_ctx->cfg.log_cfg,
|
||||||
cfg.log_cfg, &scheduleArray);
|
&scheduleArray);
|
||||||
return sched_add_entries(&scheduleArray);
|
return sched_add_entries(&scheduleArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -895,12 +683,6 @@ void sf_set_current_time()
|
||||||
srand(g_sf_global_vars.up_time);
|
srand(g_sf_global_vars.up_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
int sf_global_init(const char *log_filename_prefix)
|
|
||||||
{
|
|
||||||
sf_set_current_time();
|
|
||||||
return log_set_prefix(SF_G_BASE_PATH_STR, log_filename_prefix);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_enable_thread_notify_ex(SFContext *sf_context, const bool enabled)
|
void sf_enable_thread_notify_ex(SFContext *sf_context, const bool enabled)
|
||||||
{
|
{
|
||||||
struct nio_thread_data *thread_data;
|
struct nio_thread_data *thread_data;
|
||||||
|
|
|
||||||
225
src/sf_service.h
225
src/sf_service.h
|
|
@ -25,9 +25,6 @@
|
||||||
#include "fastcommon/ioevent.h"
|
#include "fastcommon/ioevent.h"
|
||||||
#include "fastcommon/fast_task_queue.h"
|
#include "fastcommon/fast_task_queue.h"
|
||||||
#include "sf_types.h"
|
#include "sf_types.h"
|
||||||
#include "sf_proto.h"
|
|
||||||
#include "sf_global.h"
|
|
||||||
#include "sf_nio.h"
|
|
||||||
|
|
||||||
typedef void* (*sf_alloc_thread_extra_data_callback)(const int thread_index);
|
typedef void* (*sf_alloc_thread_extra_data_callback)(const int thread_index);
|
||||||
typedef void (*sf_sig_quit_handler)(int sig);
|
typedef void (*sf_sig_quit_handler)(int sig);
|
||||||
|
|
@ -42,35 +39,29 @@ int sf_service_init_ex2(SFContext *sf_context, const char *name,
|
||||||
ThreadLoopCallback thread_loop_callback,
|
ThreadLoopCallback thread_loop_callback,
|
||||||
sf_accept_done_callback accept_done_callback,
|
sf_accept_done_callback accept_done_callback,
|
||||||
sf_set_body_length_callback set_body_length_func,
|
sf_set_body_length_callback set_body_length_func,
|
||||||
sf_alloc_recv_buffer_callback alloc_recv_buffer_func,
|
sf_deal_task_func deal_func, TaskCleanUpCallback task_cleanup_func,
|
||||||
sf_send_done_callback send_done_callback,
|
|
||||||
sf_deal_task_callback deal_func, TaskCleanUpCallback task_cleanup_func,
|
|
||||||
sf_recv_timeout_callback timeout_callback, const int net_timeout_ms,
|
sf_recv_timeout_callback timeout_callback, const int net_timeout_ms,
|
||||||
const int proto_header_size, const int task_padding_size,
|
const int proto_header_size, const int task_arg_size,
|
||||||
const int task_arg_size, const bool double_buffers,
|
TaskInitCallback init_callback, sf_release_buffer_callback
|
||||||
const bool need_shrink_task_buffer, const bool explicit_post_recv,
|
release_buffer_callback);
|
||||||
TaskInitCallback init_callback, void *init_arg,
|
|
||||||
sf_release_buffer_callback release_buffer_callback);
|
|
||||||
|
|
||||||
#define sf_service_init_ex(sf_context, name, alloc_thread_extra_data_callback,\
|
#define sf_service_init_ex(sf_context, name, alloc_thread_extra_data_callback,\
|
||||||
|
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
||||||
|
deal_func, task_cleanup_func, timeout_callback, net_timeout_ms, \
|
||||||
|
proto_header_size, task_arg_size) \
|
||||||
|
sf_service_init_ex2(sf_context, name, alloc_thread_extra_data_callback, \
|
||||||
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
||||||
send_done_callback, deal_func, task_cleanup_func, timeout_callback, \
|
deal_func, task_cleanup_func, timeout_callback, net_timeout_ms, \
|
||||||
net_timeout_ms, proto_header_size, task_arg_size) \
|
proto_header_size, task_arg_size, NULL, NULL)
|
||||||
sf_service_init_ex2(sf_context, name, alloc_thread_extra_data_callback, \
|
|
||||||
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
|
||||||
NULL, send_done_callback, deal_func, task_cleanup_func, \
|
|
||||||
timeout_callback, net_timeout_ms, proto_header_size, \
|
|
||||||
0, task_arg_size, false, true, false, NULL, NULL, NULL)
|
|
||||||
|
|
||||||
#define sf_service_init(name, alloc_thread_extra_data_callback, \
|
#define sf_service_init(name, alloc_thread_extra_data_callback, \
|
||||||
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
||||||
send_done_callback, deal_func, task_cleanup_func, timeout_callback, \
|
deal_func, task_cleanup_func, timeout_callback, net_timeout_ms, \
|
||||||
net_timeout_ms, proto_header_size, task_arg_size) \
|
proto_header_size, task_arg_size) \
|
||||||
sf_service_init_ex2(&g_sf_context, name, alloc_thread_extra_data_callback, \
|
sf_service_init_ex2(&g_sf_context, name, alloc_thread_extra_data_callback, \
|
||||||
thread_loop_callback, accept_done_callback, set_body_length_func, NULL,\
|
thread_loop_callback, accept_done_callback, set_body_length_func, \
|
||||||
send_done_callback, deal_func, task_cleanup_func, timeout_callback, \
|
deal_func, task_cleanup_func, timeout_callback, net_timeout_ms, \
|
||||||
net_timeout_ms, proto_header_size, 0, task_arg_size, false, true, \
|
proto_header_size, task_arg_size, NULL, NULL)
|
||||||
false, NULL, NULL, NULL)
|
|
||||||
|
|
||||||
int sf_service_destroy_ex(SFContext *sf_context);
|
int sf_service_destroy_ex(SFContext *sf_context);
|
||||||
|
|
||||||
|
|
@ -82,43 +73,17 @@ void sf_service_set_thread_loop_callback_ex(SFContext *sf_context,
|
||||||
#define sf_service_set_thread_loop_callback(thread_loop_callback) \
|
#define sf_service_set_thread_loop_callback(thread_loop_callback) \
|
||||||
sf_service_set_thread_loop_callback_ex(&g_sf_context, thread_loop_callback)
|
sf_service_set_thread_loop_callback_ex(&g_sf_context, thread_loop_callback)
|
||||||
|
|
||||||
static inline void sf_service_set_smart_polling_ex(SFContext *sf_context,
|
|
||||||
const FCSmartPollingConfig *smart_polling)
|
|
||||||
{
|
|
||||||
sf_context->smart_polling = *smart_polling;
|
|
||||||
}
|
|
||||||
#define sf_service_set_smart_polling(smart_polling) \
|
|
||||||
sf_service_set_smart_polling_ex(&g_sf_context, smart_polling)
|
|
||||||
|
|
||||||
static inline void sf_service_set_connect_need_log_ex(
|
|
||||||
SFContext *sf_context, const bool need_log)
|
|
||||||
{
|
|
||||||
sf_context->connect_need_log = need_log;
|
|
||||||
}
|
|
||||||
#define sf_service_set_connect_need_log(need_log) \
|
|
||||||
sf_service_set_connect_need_log_ex(&g_sf_context, need_log)
|
|
||||||
|
|
||||||
|
|
||||||
int sf_setup_signal_handler();
|
int sf_setup_signal_handler();
|
||||||
|
|
||||||
int sf_startup_schedule(pthread_t *schedule_tid);
|
int sf_startup_schedule(pthread_t *schedule_tid);
|
||||||
int sf_add_slow_log_schedule(SFSlowLogContext *slowlog_ctx);
|
int sf_add_slow_log_schedule(SFSlowLogContext *slowlog_ctx);
|
||||||
|
|
||||||
void sf_set_current_time();
|
void sf_set_current_time();
|
||||||
int sf_global_init(const char *log_filename_prefix);
|
|
||||||
|
|
||||||
int sf_socket_create_server(SFListener *listener,
|
|
||||||
int af, const char *bind_addr);
|
|
||||||
void sf_socket_close_server(SFListener *listener);
|
|
||||||
struct fast_task_info *sf_socket_accept_connection(SFListener *listener);
|
|
||||||
|
|
||||||
int sf_socket_server_ex(SFContext *sf_context);
|
int sf_socket_server_ex(SFContext *sf_context);
|
||||||
#define sf_socket_server() sf_socket_server_ex(&g_sf_context)
|
#define sf_socket_server() sf_socket_server_ex(&g_sf_context)
|
||||||
|
|
||||||
void sf_socket_close_ex(SFContext *sf_context);
|
void sf_accept_loop_ex(SFContext *sf_context, const bool block);
|
||||||
#define sf_socket_close() sf_socket_close_ex(&g_sf_context)
|
|
||||||
|
|
||||||
int sf_accept_loop_ex(SFContext *sf_context, const bool blocked);
|
|
||||||
|
|
||||||
#define sf_accept_loop() sf_accept_loop_ex(&g_sf_context, true)
|
#define sf_accept_loop() sf_accept_loop_ex(&g_sf_context, true)
|
||||||
|
|
||||||
|
|
@ -150,13 +115,14 @@ void sf_notify_all_threads_ex(SFContext *sf_context);
|
||||||
|
|
||||||
void sf_set_sig_quit_handler(sf_sig_quit_handler quit_handler);
|
void sf_set_sig_quit_handler(sf_sig_quit_handler quit_handler);
|
||||||
|
|
||||||
static inline struct fast_task_info *sf_alloc_init_task_ex(
|
int sf_init_task(struct fast_task_info *task);
|
||||||
SFNetworkHandler *handler, const int fd,
|
|
||||||
const int reffer_count)
|
static inline struct fast_task_info *sf_alloc_init_task(
|
||||||
|
SFContext *sf_context, const int sock)
|
||||||
{
|
{
|
||||||
struct fast_task_info *task;
|
struct fast_task_info *task;
|
||||||
|
|
||||||
task = free_queue_pop(&handler->fh->ctx->free_queue);
|
task = free_queue_pop();
|
||||||
if (task == NULL) {
|
if (task == NULL) {
|
||||||
logError("file: "__FILE__", line: %d, "
|
logError("file: "__FILE__", line: %d, "
|
||||||
"malloc task buff failed, you should "
|
"malloc task buff failed, you should "
|
||||||
|
|
@ -164,57 +130,19 @@ static inline struct fast_task_info *sf_alloc_init_task_ex(
|
||||||
__LINE__);
|
__LINE__);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
__sync_add_and_fetch(&task->reffer_count, 1);
|
||||||
if (task->shrinked) {
|
|
||||||
task->shrinked = false;
|
|
||||||
sf_proto_init_task_magic(task);
|
|
||||||
}
|
|
||||||
|
|
||||||
__sync_add_and_fetch(&task->reffer_count, reffer_count);
|
|
||||||
__sync_bool_compare_and_swap(&task->canceled, 1, 0);
|
__sync_bool_compare_and_swap(&task->canceled, 1, 0);
|
||||||
task->handler = handler;
|
task->ctx = sf_context;
|
||||||
task->event.fd = fd;
|
task->event.fd = sock;
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define sf_hold_task_ex(task, inc_count) fc_hold_task_ex(task, inc_count)
|
|
||||||
#define sf_hold_task(task) fc_hold_task(task)
|
|
||||||
|
|
||||||
#define sf_alloc_init_task(handler, fd) sf_alloc_init_task_ex(handler, fd, 1)
|
|
||||||
|
|
||||||
static inline struct fast_task_info *sf_alloc_init_server_task(
|
|
||||||
SFNetworkHandler *handler, const int fd)
|
|
||||||
{
|
|
||||||
const int reffer_count = 1;
|
|
||||||
struct fast_task_info *task;
|
|
||||||
|
|
||||||
if ((task=sf_alloc_init_task_ex(handler, fd, reffer_count)) != NULL) {
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
FC_URING_IS_CLIENT(task) = false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct fast_task_info *sf_alloc_init_client_task(
|
#define sf_hold_task(task) __sync_add_and_fetch(&task->reffer_count, 1)
|
||||||
SFNetworkHandler *handler)
|
|
||||||
{
|
|
||||||
const int fd = -1;
|
|
||||||
const int reffer_count = 1;
|
|
||||||
struct fast_task_info *task;
|
|
||||||
|
|
||||||
if ((task=sf_alloc_init_task_ex(handler, fd, reffer_count)) != NULL) {
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
FC_URING_IS_CLIENT(task) = true;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
return task;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_release_task(struct fast_task_info *task)
|
static inline void sf_release_task(struct fast_task_info *task)
|
||||||
{
|
{
|
||||||
|
//int reffer_count;
|
||||||
if (__sync_sub_and_fetch(&task->reffer_count, 1) == 0) {
|
if (__sync_sub_and_fetch(&task->reffer_count, 1) == 0) {
|
||||||
/*
|
/*
|
||||||
int free_count = free_queue_count();
|
int free_count = free_queue_count();
|
||||||
|
|
@ -224,100 +152,13 @@ static inline void sf_release_task(struct fast_task_info *task)
|
||||||
"used: %d, freed: %d", __LINE__, task,
|
"used: %d, freed: %d", __LINE__, task,
|
||||||
alloc_count, alloc_count - free_count, free_count);
|
alloc_count, alloc_count - free_count, free_count);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
if (SF_CTX->use_io_uring) {
|
|
||||||
task->handler->close_connection(task);
|
|
||||||
__sync_fetch_and_sub(&g_sf_global_vars.
|
|
||||||
connection_stat.current_count, 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
free_queue_push(task);
|
free_queue_push(task);
|
||||||
}
|
} else {
|
||||||
}
|
/*
|
||||||
|
logInfo("file: "__FILE__", line: %d, "
|
||||||
static inline SFNetworkHandler *sf_get_first_network_handler_ex(
|
"release task %p, current reffer: %d",
|
||||||
SFContext *sf_context)
|
__LINE__, task, reffer_count);
|
||||||
{
|
*/
|
||||||
int i;
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
SFNetworkHandler *end;
|
|
||||||
|
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
|
||||||
if (sf_context->handlers[i].af == AF_UNSPEC) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
end = sf_context->handlers[i].handlers + SF_NETWORK_HANDLER_COUNT;
|
|
||||||
for (handler=sf_context->handlers[i].handlers; handler<end; handler++) {
|
|
||||||
if (handler->enabled) {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
#define sf_get_first_network_handler() \
|
|
||||||
sf_get_first_network_handler_ex(&g_sf_context)
|
|
||||||
|
|
||||||
|
|
||||||
static inline SFNetworkHandler *sf_get_rdma_network_handler(
|
|
||||||
SFContext *sf_context)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
|
|
||||||
for (i=0; i<SF_ADDRESS_FAMILY_COUNT; i++) {
|
|
||||||
if (sf_context->handlers[i].af != AF_UNSPEC) {
|
|
||||||
handler = sf_context->handlers[i].handlers +
|
|
||||||
SF_RDMACM_NETWORK_HANDLER_INDEX;
|
|
||||||
if (handler->enabled) {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SFNetworkHandler *sf_get_rdma_network_handler2(
|
|
||||||
SFContext *sf_context1, SFContext *sf_context2)
|
|
||||||
{
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
|
|
||||||
if ((handler=sf_get_rdma_network_handler(sf_context1)) != NULL) {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return sf_get_rdma_network_handler(sf_context2);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline SFNetworkHandler *sf_get_rdma_network_handler3(
|
|
||||||
SFContext *sf_context1, SFContext *sf_context2,
|
|
||||||
SFContext *sf_context3)
|
|
||||||
{
|
|
||||||
SFNetworkHandler *handler;
|
|
||||||
|
|
||||||
if ((handler=sf_get_rdma_network_handler(sf_context1)) != NULL) {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
if ((handler=sf_get_rdma_network_handler(sf_context2)) != NULL) {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
return sf_get_rdma_network_handler(sf_context3);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bool sf_get_double_buffers_flag(FCServerGroupInfo *server_group)
|
|
||||||
{
|
|
||||||
if (server_group->comm_type == fc_comm_type_sock) {
|
|
||||||
#if IOEVENT_USE_URING
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
} else { //RDMA
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -285,7 +285,7 @@ static SFShardingHashEntry *hash_entry_reclaim(SFHtableSharding *sharding)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reclaim_count > 0) {
|
if (reclaim_count > 0) {
|
||||||
logDebug("sharding index: %d, element_count: %"PRId64", "
|
logInfo("sharding index: %d, element_count: %"PRId64", "
|
||||||
"reclaim_ttl_ms: %"PRId64" ms, reclaim_count: %"PRId64", "
|
"reclaim_ttl_ms: %"PRId64" ms, reclaim_count: %"PRId64", "
|
||||||
"reclaim_limit: %"PRId64, (int)(sharding - sharding->ctx->
|
"reclaim_limit: %"PRId64, (int)(sharding - sharding->ctx->
|
||||||
sharding_array.entries), sharding->element_count,
|
sharding_array.entries), sharding->element_count,
|
||||||
|
|
|
||||||
|
|
@ -1,94 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License, version 3
|
|
||||||
* or later ("LGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the Lesser GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "sf_shared_mbuffer.h"
|
|
||||||
|
|
||||||
static int sf_shared_mbuffer_alloc_init(void *element, void *args)
|
|
||||||
{
|
|
||||||
SFSharedMBuffer *buffer;
|
|
||||||
|
|
||||||
buffer = (SFSharedMBuffer *)((char *)element +
|
|
||||||
sizeof(struct fast_allocator_wrapper));
|
|
||||||
buffer->ctx = (SFSharedMBufferContext *)args;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int sf_shared_mbuffer_init_ex(SFSharedMBufferContext *context,
|
|
||||||
const char *name_prefix, const int buff_extra_size,
|
|
||||||
const int min_buff_size, const int max_buff_size,
|
|
||||||
const int min_alloc_once, const int64_t memory_limit,
|
|
||||||
const bool need_lock)
|
|
||||||
{
|
|
||||||
const double expect_usage_ratio = 0.75;
|
|
||||||
const int reclaim_interval = 1;
|
|
||||||
struct fast_region_info regions[32];
|
|
||||||
struct fast_mblock_object_callbacks object_callbacks;
|
|
||||||
int count;
|
|
||||||
int start;
|
|
||||||
int end;
|
|
||||||
int alloc_once;
|
|
||||||
int buff_size;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
alloc_once = (4 * 1024 * 1024) / max_buff_size;
|
|
||||||
if (alloc_once == 0) {
|
|
||||||
alloc_once = min_alloc_once;
|
|
||||||
} else {
|
|
||||||
i = min_alloc_once;
|
|
||||||
while (i < alloc_once) {
|
|
||||||
i *= 2;
|
|
||||||
}
|
|
||||||
alloc_once = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
count = 1;
|
|
||||||
buff_size = min_buff_size;
|
|
||||||
while (buff_size < max_buff_size) {
|
|
||||||
buff_size *= 2;
|
|
||||||
++count;
|
|
||||||
alloc_once *= 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
buff_size = min_buff_size;
|
|
||||||
start = 0;
|
|
||||||
end = buff_extra_size + buff_size;
|
|
||||||
FAST_ALLOCATOR_INIT_REGION(regions[0], start, end,
|
|
||||||
end - start, alloc_once);
|
|
||||||
|
|
||||||
//logInfo("[1] start: %d, end: %d, alloc_once: %d", start, end, alloc_once);
|
|
||||||
|
|
||||||
start = end;
|
|
||||||
for (i=1; i<count; i++) {
|
|
||||||
buff_size *= 2;
|
|
||||||
alloc_once /= 2;
|
|
||||||
end = buff_extra_size + buff_size;
|
|
||||||
FAST_ALLOCATOR_INIT_REGION(regions[i], start, end,
|
|
||||||
end - start, alloc_once);
|
|
||||||
//logInfo("[%d] start: %d, end: %d, alloc_once: %d", i + 1, start, end, alloc_once);
|
|
||||||
start = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
object_callbacks.init_func = sf_shared_mbuffer_alloc_init;
|
|
||||||
object_callbacks.destroy_func = NULL;
|
|
||||||
object_callbacks.args = context;
|
|
||||||
return fast_allocator_init_ex(&context->allocator, name_prefix,
|
|
||||||
sizeof(SFSharedMBuffer), &object_callbacks, regions, count,
|
|
||||||
memory_limit, expect_usage_ratio, reclaim_interval, need_lock);
|
|
||||||
}
|
|
||||||
|
|
||||||
void sf_shared_mbuffer_destroy(SFSharedMBufferContext *context)
|
|
||||||
{
|
|
||||||
fast_allocator_destroy(&context->allocator);
|
|
||||||
}
|
|
||||||
|
|
@ -1,114 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright (c) 2020 YuQing <384681@qq.com>
|
|
||||||
*
|
|
||||||
* This program is free software: you can use, redistribute, and/or modify
|
|
||||||
* it under the terms of the Lesser GNU General Public License, version 3
|
|
||||||
* or later ("LGPL"), as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
||||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the Lesser GNU General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _SF_SHARED_MBUFFER_H__
|
|
||||||
#define _SF_SHARED_MBUFFER_H__
|
|
||||||
|
|
||||||
#include "fastcommon/fc_list.h"
|
|
||||||
#include "fastcommon/fast_task_queue.h"
|
|
||||||
#include "fastcommon/shared_func.h"
|
|
||||||
#include "fastcommon/logger.h"
|
|
||||||
#include "fastcommon/fast_allocator.h"
|
|
||||||
|
|
||||||
typedef struct sf_shared_mbuffer_context {
|
|
||||||
struct fast_allocator_context allocator;
|
|
||||||
} SFSharedMBufferContext;
|
|
||||||
|
|
||||||
typedef struct sf_shared_mbuffer {
|
|
||||||
int length;
|
|
||||||
volatile int reffer_count;
|
|
||||||
SFSharedMBufferContext *ctx;
|
|
||||||
char buff[0]; //must be last
|
|
||||||
} SFSharedMBuffer;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define sf_shared_mbuffer_init(context, name_prefix, buff_extra_size, \
|
|
||||||
min_buff_size, max_buff_size, min_alloc_once, memory_limit) \
|
|
||||||
sf_shared_mbuffer_init_ex(context, name_prefix, buff_extra_size, \
|
|
||||||
min_buff_size, max_buff_size, min_alloc_once, memory_limit, true)
|
|
||||||
|
|
||||||
int sf_shared_mbuffer_init_ex(SFSharedMBufferContext *context,
|
|
||||||
const char *name_prefix, const int buff_extra_size,
|
|
||||||
const int min_buff_size, const int max_buff_size,
|
|
||||||
const int min_alloc_once, const int64_t memory_limit,
|
|
||||||
const bool need_lock);
|
|
||||||
|
|
||||||
void sf_shared_mbuffer_destroy(SFSharedMBufferContext *context);
|
|
||||||
|
|
||||||
#define sf_shared_mbuffer_alloc(context, buffer_size) \
|
|
||||||
sf_shared_mbuffer_alloc_ex(context, buffer_size, 1)
|
|
||||||
|
|
||||||
static inline SFSharedMBuffer *sf_shared_mbuffer_alloc_ex(
|
|
||||||
SFSharedMBufferContext *context, const int buffer_size,
|
|
||||||
const int init_reffer_count)
|
|
||||||
{
|
|
||||||
SFSharedMBuffer *buffer;
|
|
||||||
int sleep_ms;
|
|
||||||
|
|
||||||
sleep_ms = 5;
|
|
||||||
while ((buffer=fast_allocator_alloc(&context->allocator,
|
|
||||||
buffer_size)) == NULL)
|
|
||||||
{
|
|
||||||
if (sleep_ms < 100) {
|
|
||||||
sleep_ms *= 2;
|
|
||||||
}
|
|
||||||
fc_sleep_ms(sleep_ms);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (init_reffer_count > 0) {
|
|
||||||
__sync_add_and_fetch(&buffer->reffer_count, init_reffer_count);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
logInfo("file: "__FILE__", line: %d, "
|
|
||||||
"alloc shared buffer: %p, buff: %p, reffer_count: %d",
|
|
||||||
__LINE__, buffer, buffer->buff, __sync_add_and_fetch(&buffer->reffer_count, 0));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_shared_mbuffer_hold(SFSharedMBuffer *buffer)
|
|
||||||
{
|
|
||||||
__sync_add_and_fetch(&buffer->reffer_count, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_shared_mbuffer_release(SFSharedMBuffer *buffer)
|
|
||||||
{
|
|
||||||
if (__sync_sub_and_fetch(&buffer->reffer_count, 1) == 0) {
|
|
||||||
/*
|
|
||||||
logInfo("file: "__FILE__", line: %d, "
|
|
||||||
"free shared buffer: %p", __LINE__, buffer);
|
|
||||||
*/
|
|
||||||
fast_allocator_free(&buffer->ctx->allocator, buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void sf_release_task_shared_mbuffer(struct fast_task_info *task)
|
|
||||||
{
|
|
||||||
SFSharedMBuffer *mbuffer;
|
|
||||||
mbuffer = fc_list_entry(task->recv_body, SFSharedMBuffer, buff);
|
|
||||||
sf_shared_mbuffer_release(mbuffer);
|
|
||||||
task->recv_body = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
206
src/sf_types.h
206
src/sf_types.h
|
|
@ -34,170 +34,41 @@
|
||||||
#define SF_SERVER_TASK_TYPE_CHANNEL_HOLDER 101 //for request idempotency
|
#define SF_SERVER_TASK_TYPE_CHANNEL_HOLDER 101 //for request idempotency
|
||||||
#define SF_SERVER_TASK_TYPE_CHANNEL_USER 102 //for request idempotency
|
#define SF_SERVER_TASK_TYPE_CHANNEL_USER 102 //for request idempotency
|
||||||
|
|
||||||
#define SF_ADDRESS_FAMILY_COUNT 2
|
typedef void (*sf_accept_done_callback)(struct fast_task_info *task,
|
||||||
#define SF_IPV4_ADDRESS_FAMILY_INDEX 0
|
const bool bInnerPort);
|
||||||
#define SF_IPV6_ADDRESS_FAMILY_INDEX 1
|
|
||||||
|
|
||||||
#define SF_NETWORK_HANDLER_COUNT 2
|
|
||||||
#define SF_SOCKET_NETWORK_HANDLER_INDEX 0
|
|
||||||
#define SF_RDMACM_NETWORK_HANDLER_INDEX 1
|
|
||||||
|
|
||||||
#define SF_BINLOG_BUFFER_PRODUCER_DATA_LENGTH(bf) ((bf).data_end - (bf).buff)
|
|
||||||
#define SF_BINLOG_BUFFER_PRODUCER_BUFF_REMAIN(bf) ((bf).buff_end - (bf).data_end)
|
|
||||||
#define SF_BINLOG_BUFFER_CONSUMER_DATA_LENGTH(bf) ((bf).current - (bf).buff)
|
|
||||||
#define SF_BINLOG_BUFFER_CONSUMER_DATA_REMAIN(bf) ((bf).data_end - (bf).current)
|
|
||||||
|
|
||||||
typedef int (*sf_accept_done_callback)(struct fast_task_info *task,
|
|
||||||
const in_addr_64_t client_addr, const bool bInnerPort);
|
|
||||||
typedef int (*sf_set_body_length_callback)(struct fast_task_info *task);
|
typedef int (*sf_set_body_length_callback)(struct fast_task_info *task);
|
||||||
typedef char *(*sf_alloc_recv_buffer_callback)(struct fast_task_info *task,
|
typedef int (*sf_deal_task_func)(struct fast_task_info *task, const int stage);
|
||||||
const int buff_size, bool *new_alloc);
|
|
||||||
typedef int (*sf_deal_task_callback)(struct fast_task_info *task, const int stage);
|
|
||||||
typedef int (*sf_recv_timeout_callback)(struct fast_task_info *task);
|
typedef int (*sf_recv_timeout_callback)(struct fast_task_info *task);
|
||||||
typedef int (*sf_send_done_callback)(struct fast_task_info *task,
|
|
||||||
const int length, int *next_stage);
|
|
||||||
typedef void (*sf_connect_done_callback)(struct fast_task_info *task,
|
|
||||||
const int err_no);
|
|
||||||
|
|
||||||
/* calback for release iovec buffer */
|
/* calback for release iovec buffer */
|
||||||
typedef void (*sf_release_buffer_callback)(struct fast_task_info *task);
|
typedef void (*sf_release_buffer_callback)(struct fast_task_info *task);
|
||||||
|
|
||||||
typedef int (*sf_error_handler_callback)(const int errnum);
|
typedef int (*sf_error_handler_callback)(const int errnum);
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
sf_comm_action_continue = 'c',
|
|
||||||
sf_comm_action_break = 'b',
|
|
||||||
sf_comm_action_finish = 'f'
|
|
||||||
} SFCommAction;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
sf_address_family_auto = 0,
|
|
||||||
sf_address_family_ipv4 = 1,
|
|
||||||
sf_address_family_ipv6 = 2,
|
|
||||||
sf_address_family_both = 3
|
|
||||||
} SFAddressFamily;
|
|
||||||
|
|
||||||
struct ibv_pd;
|
|
||||||
struct sf_listener;
|
|
||||||
|
|
||||||
typedef int (*sf_get_connection_size_callback)();
|
|
||||||
typedef int (*sf_init_connection_callback)(
|
|
||||||
struct fast_task_info *task, void *arg);
|
|
||||||
#define sf_alloc_pd_callback fc_alloc_pd_callback
|
|
||||||
|
|
||||||
typedef int (*sf_create_server_callback)(struct sf_listener
|
|
||||||
*listener, int af, const char *bind_addr);
|
|
||||||
typedef void (*sf_close_server_callback)(struct sf_listener *listener);
|
|
||||||
typedef struct fast_task_info * (*sf_accept_connection_callback)(
|
|
||||||
struct sf_listener *listener);
|
|
||||||
typedef int (*sf_async_connect_server_callback)(struct fast_task_info *task);
|
|
||||||
typedef int (*sf_async_connect_check_callback)(struct fast_task_info *task);
|
|
||||||
typedef void (*sf_close_connection_callback)(struct fast_task_info *task);
|
|
||||||
|
|
||||||
typedef ssize_t (*sf_send_data_callback)(struct fast_task_info *task,
|
|
||||||
SFCommAction *action, bool *send_done);
|
|
||||||
typedef ssize_t (*sf_recv_data_callback)(struct fast_task_info *task,
|
|
||||||
const bool call_post_recv, SFCommAction *action);
|
|
||||||
typedef int (*sf_post_recv_callback)(struct fast_task_info *task);
|
|
||||||
|
|
||||||
struct sf_network_handler;
|
|
||||||
typedef struct sf_listener {
|
|
||||||
struct sf_network_handler *handler;
|
|
||||||
int port;
|
|
||||||
bool enabled;
|
|
||||||
bool is_inner;
|
|
||||||
union {
|
|
||||||
int sock; //for socket
|
|
||||||
void *id; //for rdma_cm
|
|
||||||
};
|
|
||||||
struct sockaddr_in inaddr; //for accept
|
|
||||||
} SFListener;
|
|
||||||
|
|
||||||
struct sf_context;
|
|
||||||
struct sf_address_family_handler;
|
|
||||||
|
|
||||||
typedef struct sf_network_handler {
|
|
||||||
bool enabled;
|
|
||||||
bool explicit_post_recv;
|
|
||||||
FCCommunicationType comm_type;
|
|
||||||
struct sf_address_family_handler *fh;
|
|
||||||
struct ibv_pd *pd;
|
|
||||||
|
|
||||||
SFListener inner;
|
|
||||||
SFListener outer;
|
|
||||||
|
|
||||||
/* for server side */
|
|
||||||
sf_get_connection_size_callback get_connection_size;
|
|
||||||
sf_init_connection_callback init_connection;
|
|
||||||
sf_alloc_pd_callback alloc_pd;
|
|
||||||
sf_create_server_callback create_server;
|
|
||||||
sf_close_server_callback close_server;
|
|
||||||
sf_accept_connection_callback accept_connection;
|
|
||||||
|
|
||||||
/* for client side */
|
|
||||||
sf_async_connect_server_callback async_connect_server;
|
|
||||||
sf_async_connect_check_callback async_connect_check;
|
|
||||||
|
|
||||||
/* server and client both */
|
|
||||||
sf_close_connection_callback close_connection;
|
|
||||||
|
|
||||||
sf_send_data_callback send_data;
|
|
||||||
sf_recv_data_callback recv_data;
|
|
||||||
sf_post_recv_callback post_recv; //for rdma
|
|
||||||
} SFNetworkHandler;
|
|
||||||
|
|
||||||
typedef struct sf_nio_callbacks {
|
|
||||||
TaskCleanUpCallback task_cleanup;
|
|
||||||
sf_deal_task_callback deal_task;
|
|
||||||
sf_set_body_length_callback set_body_length;
|
|
||||||
sf_alloc_recv_buffer_callback alloc_recv_buffer;
|
|
||||||
sf_accept_done_callback accept_done;
|
|
||||||
sf_connect_done_callback connect_done;
|
|
||||||
sf_send_done_callback send_done;
|
|
||||||
sf_recv_timeout_callback task_timeout;
|
|
||||||
sf_release_buffer_callback release_buffer;
|
|
||||||
} SFNIOCallbacks;
|
|
||||||
|
|
||||||
typedef struct sf_address_family_handler {
|
|
||||||
int af; //AF_UNSPEC for disabled
|
|
||||||
SFNetworkHandler handlers[SF_NETWORK_HANDLER_COUNT];
|
|
||||||
char inner_bind_addr[IP_ADDRESS_SIZE];
|
|
||||||
char outer_bind_addr[IP_ADDRESS_SIZE];
|
|
||||||
struct sf_context *ctx;
|
|
||||||
} SFAddressFamilyHandler;
|
|
||||||
|
|
||||||
typedef struct sf_net_buffer_config {
|
|
||||||
int connect_timeout;
|
|
||||||
int network_timeout;
|
|
||||||
int max_connections;
|
|
||||||
int max_pkg_size;
|
|
||||||
int min_buff_size;
|
|
||||||
int max_buff_size;
|
|
||||||
} SFNetBufferConfig;
|
|
||||||
|
|
||||||
typedef struct sf_context {
|
typedef struct sf_context {
|
||||||
char name[64];
|
char name[64];
|
||||||
struct nio_thread_data *thread_data;
|
struct nio_thread_data *thread_data;
|
||||||
volatile int thread_count;
|
volatile int thread_count;
|
||||||
|
int outer_sock;
|
||||||
|
int inner_sock;
|
||||||
|
|
||||||
bool is_client; //since v1.2.5
|
int outer_port;
|
||||||
bool use_io_uring; //since v1.2.9
|
int inner_port;
|
||||||
bool use_send_zc; //since v1.2.9
|
|
||||||
SFAddressFamily address_family;
|
|
||||||
SFAddressFamilyHandler handlers[SF_ADDRESS_FAMILY_COUNT];
|
|
||||||
|
|
||||||
SFNetBufferConfig net_buffer_cfg;
|
|
||||||
|
|
||||||
int accept_threads;
|
int accept_threads;
|
||||||
int work_threads;
|
int work_threads;
|
||||||
|
|
||||||
int header_size;
|
char inner_bind_addr[IP_ADDRESS_SIZE];
|
||||||
bool realloc_task_buffer;
|
char outer_bind_addr[IP_ADDRESS_SIZE];
|
||||||
bool connect_need_log; //for client connect
|
|
||||||
FCSmartPollingConfig smart_polling;
|
|
||||||
|
|
||||||
SFNIOCallbacks callbacks;
|
int header_size;
|
||||||
struct fast_task_queue free_queue;
|
bool remove_from_ready_list;
|
||||||
|
bool realloc_task_buffer;
|
||||||
|
sf_deal_task_func deal_task;
|
||||||
|
sf_set_body_length_callback set_body_length;
|
||||||
|
sf_accept_done_callback accept_done_func;
|
||||||
|
TaskCleanUpCallback task_cleanup_func;
|
||||||
|
sf_recv_timeout_callback timeout_callback;
|
||||||
|
sf_release_buffer_callback release_buffer_callback;
|
||||||
} SFContext;
|
} SFContext;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -237,11 +108,10 @@ typedef struct sf_binlog_file_position {
|
||||||
} SFBinlogFilePosition;
|
} SFBinlogFilePosition;
|
||||||
|
|
||||||
typedef struct server_binlog_buffer {
|
typedef struct server_binlog_buffer {
|
||||||
char *buff; //the buffer pointer
|
char *buff; //the buffer pointer
|
||||||
char *current; //for the consumer
|
char *current; //for the consumer
|
||||||
char *data_end; //data end ptr
|
char *end; //data end ptr
|
||||||
char *buff_end; //buffer end ptr
|
int size; //the buffer size (capacity)
|
||||||
int size; //the buffer size (capacity)
|
|
||||||
} SFBinlogBuffer;
|
} SFBinlogBuffer;
|
||||||
|
|
||||||
typedef struct sf_space_stat {
|
typedef struct sf_space_stat {
|
||||||
|
|
@ -367,41 +237,11 @@ typedef struct sf_cluster_config {
|
||||||
|
|
||||||
typedef struct sf_synchronize_context {
|
typedef struct sf_synchronize_context {
|
||||||
pthread_lock_cond_pair_t lcp;
|
pthread_lock_cond_pair_t lcp;
|
||||||
int result;
|
|
||||||
union {
|
union {
|
||||||
bool finished;
|
bool finished;
|
||||||
bool ready;
|
int result;
|
||||||
int waiting_count;
|
int waiting_count;
|
||||||
};
|
};
|
||||||
} SFSynchronizeContext;
|
} SFSynchronizeContext;
|
||||||
|
|
||||||
typedef enum sf_election_quorum {
|
|
||||||
sf_election_quorum_auto,
|
|
||||||
sf_election_quorum_any,
|
|
||||||
sf_election_quorum_majority
|
|
||||||
} SFElectionQuorum;
|
|
||||||
|
|
||||||
typedef enum sf_replication_quorum {
|
|
||||||
sf_replication_quorum_auto,
|
|
||||||
sf_replication_quorum_any,
|
|
||||||
sf_replication_quorum_majority,
|
|
||||||
sf_replication_quorum_smart
|
|
||||||
} SFReplicationQuorum;
|
|
||||||
|
|
||||||
typedef struct sf_block_key {
|
|
||||||
int64_t oid; //object id
|
|
||||||
int64_t offset; //aligned by block size
|
|
||||||
uint64_t hash_code;
|
|
||||||
} SFBlockKey;
|
|
||||||
|
|
||||||
typedef struct sf_slice_size {
|
|
||||||
int offset; //offset within the block
|
|
||||||
int length; //slice length
|
|
||||||
} SFSliceSize;
|
|
||||||
|
|
||||||
typedef struct sf_block_slice_key_info {
|
|
||||||
SFBlockKey block;
|
|
||||||
SFSliceSize slice;
|
|
||||||
} SFBlockSliceKeyInfo;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -281,7 +281,7 @@ int sf_logger_init(LogContext *pContext, const char *filename_prefix)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleEntry *sf_logger_set_schedule_entries(struct log_context *pContext,
|
ScheduleEntry *sf_logger_set_schedule_entry(struct log_context *pContext,
|
||||||
SFLogConfig *log_cfg, ScheduleEntry *pScheduleEntry)
|
SFLogConfig *log_cfg, ScheduleEntry *pScheduleEntry)
|
||||||
{
|
{
|
||||||
INIT_SCHEDULE_ENTRY(*pScheduleEntry, sched_generate_next_id(),
|
INIT_SCHEDULE_ENTRY(*pScheduleEntry, sched_generate_next_id(),
|
||||||
|
|
@ -311,8 +311,6 @@ ScheduleEntry *sf_logger_set_schedule_entries(struct log_context *pContext,
|
||||||
const char *sf_strerror(const int errnum)
|
const char *sf_strerror(const int errnum)
|
||||||
{
|
{
|
||||||
switch (errnum) {
|
switch (errnum) {
|
||||||
case SF_CLUSTER_ERROR_BINLOG_MISSED:
|
|
||||||
return "binlog missed";
|
|
||||||
case SF_CLUSTER_ERROR_BINLOG_INCONSISTENT:
|
case SF_CLUSTER_ERROR_BINLOG_INCONSISTENT:
|
||||||
return "binlog inconsistent";
|
return "binlog inconsistent";
|
||||||
case SF_CLUSTER_ERROR_LEADER_INCONSISTENT:
|
case SF_CLUSTER_ERROR_LEADER_INCONSISTENT:
|
||||||
|
|
@ -331,8 +329,6 @@ const char *sf_strerror(const int errnum)
|
||||||
return STRERROR(EINVAL);
|
return STRERROR(EINVAL);
|
||||||
case SF_ERROR_EAGAIN:
|
case SF_ERROR_EAGAIN:
|
||||||
return STRERROR(EAGAIN);
|
return STRERROR(EAGAIN);
|
||||||
case SF_ERROR_EINPROGRESS:
|
|
||||||
return STRERROR(EINPROGRESS);
|
|
||||||
case SF_ERROR_EOVERFLOW:
|
case SF_ERROR_EOVERFLOW:
|
||||||
return STRERROR(EOVERFLOW);
|
return STRERROR(EOVERFLOW);
|
||||||
case SF_ERROR_ENODATA:
|
case SF_ERROR_ENODATA:
|
||||||
|
|
|
||||||
|
|
@ -96,14 +96,14 @@ void sf_parse_cmd_option_bool(int argc, char *argv[],
|
||||||
|
|
||||||
int sf_logger_init(LogContext *pContext, const char *filename_prefix);
|
int sf_logger_init(LogContext *pContext, const char *filename_prefix);
|
||||||
|
|
||||||
ScheduleEntry *sf_logger_set_schedule_entries(struct log_context *pContext,
|
ScheduleEntry *sf_logger_set_schedule_entry(struct log_context *pContext,
|
||||||
SFLogConfig *log_cfg, ScheduleEntry *pScheduleEntry);
|
SFLogConfig *log_cfg, ScheduleEntry *pScheduleEntry);
|
||||||
|
|
||||||
static inline void sf_logger_setup_schedule(struct log_context *pContext,
|
static inline void sf_setup_schedule(struct log_context *pContext,
|
||||||
SFLogConfig *log_cfg, ScheduleArray *scheduleArray)
|
SFLogConfig *log_cfg, ScheduleArray *scheduleArray)
|
||||||
{
|
{
|
||||||
ScheduleEntry *scheduleEntry;
|
ScheduleEntry *scheduleEntry;
|
||||||
scheduleEntry = sf_logger_set_schedule_entries(pContext,
|
scheduleEntry = sf_logger_set_schedule_entry(pContext,
|
||||||
log_cfg, scheduleArray->entries);
|
log_cfg, scheduleArray->entries);
|
||||||
scheduleArray->count = scheduleEntry - scheduleArray->entries;
|
scheduleArray->count = scheduleEntry - scheduleArray->entries;
|
||||||
}
|
}
|
||||||
|
|
@ -117,20 +117,12 @@ static inline int sf_unify_errno(const int errnum)
|
||||||
return SF_ERROR_EINVAL;
|
return SF_ERROR_EINVAL;
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
return SF_ERROR_EAGAIN;
|
return SF_ERROR_EAGAIN;
|
||||||
case EINPROGRESS:
|
|
||||||
return SF_ERROR_EINPROGRESS;
|
|
||||||
case EOVERFLOW:
|
case EOVERFLOW:
|
||||||
return SF_ERROR_EOVERFLOW;
|
return SF_ERROR_EOVERFLOW;
|
||||||
case EOPNOTSUPP:
|
case EOPNOTSUPP:
|
||||||
return SF_ERROR_EOPNOTSUPP;
|
return SF_ERROR_EOPNOTSUPP;
|
||||||
case ENODATA:
|
case ENODATA:
|
||||||
return SF_ERROR_ENODATA;
|
return SF_ERROR_ENODATA;
|
||||||
case ENOLINK:
|
|
||||||
return SF_ERROR_ENOLINK;
|
|
||||||
case ENOTEMPTY:
|
|
||||||
return SF_ERROR_ENOTEMPTY;
|
|
||||||
case ELOOP:
|
|
||||||
return SF_ERROR_ELOOP;
|
|
||||||
default:
|
default:
|
||||||
return errnum;
|
return errnum;
|
||||||
}
|
}
|
||||||
|
|
@ -149,8 +141,6 @@ static inline int sf_localize_errno(int errnum)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
case SF_ERROR_EAGAIN:
|
case SF_ERROR_EAGAIN:
|
||||||
return EAGAIN;
|
return EAGAIN;
|
||||||
case SF_ERROR_EINPROGRESS:
|
|
||||||
return EINPROGRESS;
|
|
||||||
case SF_ERROR_EOVERFLOW:
|
case SF_ERROR_EOVERFLOW:
|
||||||
return EOVERFLOW;
|
return EOVERFLOW;
|
||||||
case SF_ERROR_EOPNOTSUPP:
|
case SF_ERROR_EOPNOTSUPP:
|
||||||
|
|
@ -159,12 +149,6 @@ static inline int sf_localize_errno(int errnum)
|
||||||
return ENODATA;
|
return ENODATA;
|
||||||
case SF_SESSION_ERROR_NOT_EXIST:
|
case SF_SESSION_ERROR_NOT_EXIST:
|
||||||
return EPERM;
|
return EPERM;
|
||||||
case SF_ERROR_ENOLINK:
|
|
||||||
return ENOLINK;
|
|
||||||
case SF_ERROR_ENOTEMPTY:
|
|
||||||
return ENOTEMPTY;
|
|
||||||
case SF_ERROR_ELOOP:
|
|
||||||
return ELOOP;
|
|
||||||
default:
|
default:
|
||||||
return errnum;
|
return errnum;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue