Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

re-implement shared-state from scratch in modern C++ #1067

Merged
merged 6 commits into from
Feb 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 9 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
build
*~
*.kate-swp
luacov.stats.out
tools/ansible/files/generic-rootfs.tar.gz
tools/ansible/files/ramfs.bzImage

# Vim text editor swap files
**/*~

# Kate KDE text editor swap files
**/*.kate-swp

# Ignore OpenWrt source tree override symlink
**/git-src
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Shared State
#
# Copyright (C) 2023-2024 Gioacchino Mazzurco <[email protected]>
# Copyright (c) 2023 Javier Jorge <[email protected]>
# Copyright (c) 2023 Instituto Nacional de Tecnología Industrial
# Copyright (C) 2023 Asociación Civil Altermundi <[email protected]>
# Copyright (C) 2023-2024 Asociación Civil Altermundi <[email protected]>
#
# This program is free software: you can redistribute it and/or modify it under
# the terms of the GNU Affero General Public License as published by the
Expand All @@ -23,13 +24,13 @@ include $(TOPDIR)/rules.mk
GIT_COMMIT_DATE:=$(shell git log -n 1 --pretty=%ad --date=short . )
GIT_COMMIT_TSTAMP:=$(shell git log -n 1 --pretty=%at . )

PKG_NAME:=shared-state-async-node
PKG_NAME:=shared-state-async
PKG_VERSION=$(GIT_COMMIT_DATE)-$(GIT_COMMIT_TSTAMP)

PKG_SOURCE_PROTO:=git
PKG_SOURCE_URL:=https://github.com/libremesh/shared-state-async-node.git
PKG_SOURCE_VERSION:= 691c4412a84bb8142c73b4f5ff319f025b3973f7
PKG_MAINTAINER:=Javier Jorge <[email protected]>
PKG_SOURCE_URL:=https://github.com/libremesh/shared-state-async.git
PKG_SOURCE_VERSION:=ac7b3be5d1990195b9eee09888ac97daf08c82c5
PKG_MAINTAINER:=Asociación Civil Altermundi <[email protected]>
PKG_LICENSE:=AGPL-3.0

HOST_BUILD_PREFIX:=$(STAGING_DIR_HOST)
Expand All @@ -38,30 +39,40 @@ include $(INCLUDE_DIR)/package.mk
include $(INCLUDE_DIR)/cmake.mk
include $(INCLUDE_DIR)/host-build.mk

# Package definition; instructs on how and where our package will appear in the overall configuration menu ('make menuconfig')
define Package/$(PKG_NAME)
TITLE:=Very small server written in c++ (20)
TITLE:=shared-state C++ async re-implementation
CATEGORY:=LibreMesh
SECTION:=experimental
# TODO: Statically linking libstdcpp instead of depending on it and then
# stripping unused symbols might reduce space usage, until this is the
# only package to use it
DEPENDS:=+libstdcpp
endef

define Package/$(PKG_NAME)/description
Very small server written in c++ (20) implementing corotuines to handle incomming requests and request requirements.
shared-state re-written in C++20 and corotuines to handle information exchange between network nodes more efficiently.
endef

# Otherwise OpenWrt's CPPFLAGS are ignored
TARGET_CFLAGS += $(TARGET_CPPFLAGS)

CMAKE_OPTIONS += \
-DCMAKE_VERBOSE_MAKEFILE=TRUE \
-DENABLE_SHARED=YES \
-DENABLE_STATIC=NO \
-DENABLE_TESTS=NO
CMAKE_OPTIONS += -DCMAKE_VERBOSE_MAKEFILE=ON

# Disable Cpptrace as it depends on zlib and doesn't seems to work anyway on
# OpenWrt even with CONFIG_DEBUG=y it prints out
# Stack trace (most recent call first):
# #0 0x00000000
# #1 0x00000000
# #2 0x00000000
CMAKE_OPTIONS += -DSS_CPPTRACE_STACKTRACE=OFF


define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/main $(1)/usr/bin/$(PKG_NAME)
$(INSTALL_BIN) $(PKG_BUILD_DIR)/shared-state-async $(1)/usr/bin/
$(CP) ./files/* $(1)/

# TODO: Remove this line once discovery is reimplemented in C++
$(CP) ../shared-state/files/usr/bin/shared-state-get_candidates_neigh $(1)/usr/bin/shared-state-async-discover
endef

$(eval $(call BuildPackage,$(PKG_NAME)))
49 changes: 49 additions & 0 deletions packages/shared-state-async/README.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

.Build with debugging enabled
--------------------------------------------------------------------------------
make package/feeds/libremesh/shared-state-async/clean package/feeds/libremesh/shared-state-async/compile -j$(nproc) CONFIG_DEBUG=y
--------------------------------------------------------------------------------

.Copy on verde e blu
--------------------------------------------------------------------------------
scp -O bin/packages/mips_24kc/libremesh/shared-state-async_*.ipk root@[fe80::ea94:f6ff:fe68:3364%usbe1]:/tmp/
scp -O bin/packages/mips_24kc/libremesh/shared-state-async_*.ipk root@[fe80::6670:2ff:fede:c51e%usbe1]:/tmp/
--------------------------------------------------------------------------------

.Install
--------------------------------------------------------------------------------
opkg install --force-reinstall /tmp/shared-state-async_*.ipk
--------------------------------------------------------------------------------

.Run with gdb
--------------------------------------------------------------------------------
gdbserver :9000 shared-state-async
--------------------------------------------------------------------------------

.Attach with remote OpenWrt gdb
--------------------------------------------------------------------------------
scripts/remote-gdb [fe80::ea94:f6ff:fe68:3364%usbe0]:9000 ./build_dir/target-mips_24kc_musl/shared-state-async-*/shared-state-async

scripts/remote-gdb [fe80::6670:2ff:fede:c51e%usbe0]:9000 ./build_dir/target-mips_24kc_musl/shared-state-async-*/shared-state-async
break shared-state-async.cc:55
run listen
run sync bat-hosts fe80::ea94:f6ff:fe68:3364%br-lan
run sync bat-hosts fe80::d237:45ff:fefc:3cdd%br-lan
--------------------------------------------------------------------------------

.Stressing the server
--------------------------------------------------------------------------------
while Builds/build-lime-shared-state-async-node-Desktop-Debug/shared-state-async sync bat-hosts fe80::ea94:f6ff:fe68:3364%usbeth0; do echo ------------------------------------------------------------------- ;done

while shared-state-async sync bat-hosts fe80::ea94:f6ff:fe68:3364%br-lan; do echo ------------------------------------------------------------------- ;done

--------------------------------------------------------------------------------


=== Interesting Readings

https://openwrt.org/docs/guide-developer/gdb

VoCore2: Develop for OpenWrt on Qt Creator
https://vonger.cn/?p=14657

34 changes: 34 additions & 0 deletions packages/shared-state-async/files/etc/init.d/shared-state-async
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/sh /etc/rc.common

USE_PROCD=1
START=30

handle_data_type_config()
{
local cfg="$1"

config_get name "$cfg" name
config_get scope "$cfg" scope
config_get ttl "$cfg" ttl
config_get update_interval "$cfg" update_interval

shared-state-async register $name $scope $update_interval $ttl
}

start_service()
{
sharedStateConfDir="/tmp/shared-state/"
sharedStateConfFile="${sharedStateConfDir}/shared-state-async.conf"
mkdir -p "$sharedStateConfDir"
echo "{}" > "$sharedStateConfFile"

config_load shared-state
config_foreach handle_data_type_config dataType

procd_open_instance
procd_set_param command shared-state-async peer
procd_set_param respawn
procd_set_param stderr 1
procd_set_param term_timeout 10
procd_close_instance
}
8 changes: 4 additions & 4 deletions packages/shared-state-bat_hosts/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (C) 2019 Gioacchino Mazzurco <[email protected]>
# Copyright (C) 2019-2024 Gioacchino Mazzurco <[email protected]>
#
# This is free software, licensed under the GNU Affero General Public License v3.
#
Expand All @@ -17,10 +17,10 @@ include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
TITLE:=bat-hosts module for shared-state
CATEGORY:=LibreMesh
MAINTAINER:=Gioacchino Mazzurco <gio@altermundi.net>
MAINTAINER:=Asociación Civil Altermundi <info@altermundi.net>
URL:=http://libremesh.org
DEPENDS:=+lua +luci-lib-jsonc +random-numgen \
shared-state +lime-system +luci-lib-nixio +libubus-lua
DEPENDS:=+libubus-lua +lime-system +lua +luci-lib-jsonc +luci-lib-nixio \
shared-state-async
PKGARCH:=all
endef

Expand Down
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
#!/bin/sh
[ "x$ACTION" == "xifup" ] && ((sleep 30; shared-state-publish_bat_hosts; shared-state sync bat-hosts)&)
[ "x$ACTION" == "xifup" ] && ((sleep 30; shared-state-publish_bat_hosts; shared-state-async sync bat-hosts)&)

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ unique_append()
grep -qF "$1" "$2" || echo "$1" >> "$2"
}

uci set shared-state.bat_hosts=dataType
uci set shared-state.bat_hosts.name='bat-hosts'
uci set shared-state.bat_hosts.scope='community'
uci set shared-state.bat_hosts.ttl='2400'
uci set shared-state.bat_hosts.update_interval='30'
uci commit shared-state

unique_append \
'*/5 * * * * ((sleep $(($(random-numgen) % 120)); shared-state sync bat-hosts &> /dev/null)&)'\
'*/30 * * * * ((sleep $(($RANDOM % 120)); shared-state-publish_bat_hosts &> /dev/null)&)' \
/etc/crontabs/root

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,7 @@

--! LibreMesh
--! Copyright (C) 2019 Gioacchino Mazzurco <[email protected]>
--!
--! This program is free software: you can redistribute it and/or modify
--! it under the terms of the GNU Affero General Public License as
--! published by the Free Software Foundation, either version 3 of the
--! License, or (at your option) any later version.
--!
--! 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. See the
--! GNU Affero General Public License for more details.
--!
--! You should have received a copy of the GNU Affero General Public License
--! along with this program. If not, see <http://www.gnu.org/licenses/>.
--! SPDX-License-Identifier: AGPL-3.0-only

local fs = require("nixio.fs")
local JSON = require("luci.jsonc")
Expand All @@ -35,4 +23,4 @@ for ifname in fs.dir(ifacesPath) do
end
end

io.popen("shared-state insert bat-hosts", "w"):write(JSON.stringify(batHostTable))
io.popen("shared-state-async insert bat-hosts", "w"):write(JSON.stringify(batHostTable))
15 changes: 4 additions & 11 deletions packages/shared-state-bat_hosts/files/usr/lib/lua/bat-hosts.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
local shared_state = require("shared-state")
local JSON = require("luci.jsonc")
local utils = require("lime.utils")

local bat_hosts = {}
Expand All @@ -21,18 +22,10 @@ function bat_hosts.bathost_deserialize(hostname_plus_iface)
end

function bat_hosts.get_bathost(mac, outgoing_iface)
local sharedState = shared_state.SharedState:new('bat-hosts')
local bathosts = sharedState:get()
local bathosts = JSON.stringify(
io.popen("shared-state-async get bat-hosts", "r"):read("*all") )
local bathost = bathosts[mac:lower()]
if bathost == nil and outgoing_iface then
local ipv6ll = utils.mac2ipv6linklocal(mac) .. "%" .. outgoing_iface
sharedState:sync({ ipv6ll })
bathosts = sharedState:get()
bathost = bathosts[mac:lower()]
end
if bathost == nil then
return
end
if bathost == nil then return end
local hostname, iface = bat_hosts.bathost_deserialize(bathost.data)
return { hostname = hostname, iface = iface }
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/usr/bin/lua

--! LibreMesh
--! Copyright (C) 2019-2024 Gioacchino Mazzurco <[email protected]>
--! Copyright (C) 2024 Asociación Civil Altermundi <[email protected]>
--! SPDX-License-Identifier: AGPL-3.0-only

local JSON = require("luci.jsonc")

local outputTable = {}

for key,value in pairs(JSON.parse(io.stdin:read("*all")) ) do
table.insert(outputTable, key.." "..value)
end

io.output("/etc/bat-hosts"):write(table.concat(outputTable,"\n").."\n")
Loading
Loading