Skip to content

Commit

Permalink
Merge pull request #2 from jeffijoe/feat/mimalloc
Browse files Browse the repository at this point in the history
Use mimalloc as the global allocator + remove unused hashmap of messages
  • Loading branch information
jeffijoe authored May 22, 2023
2 parents c4e7199 + 547297e commit a7859fd
Show file tree
Hide file tree
Showing 9 changed files with 110 additions and 64 deletions.
15 changes: 14 additions & 1 deletion .cargo/config.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
# Custom linker + flags for certain targets.

[target.arm-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"
# This target is 32-bit, and mimalloc uses CAS operations
# which are not implemented in hardware on 32-bit architectures,
# so we need to tell the linker to include the `atomic` library.
rustflags = ["-C", "link-args=-latomic"]

[target.aarch64-unknown-linux-gnu]
linker = "aarch64-linux-gnu-gcc"

[target.aarch64-unknown-linux-musl]
# The included linker for this target doesn't seem to work.
linker = "rust-lld"

[target.armv7-unknown-linux-gnueabihf]
linker = "arm-linux-gnueabihf-gcc"

# # Use the sparse registry protocol for Cargo.
[target.x86_64-unknown-linux-musl]
linker = "musl-gcc"

# Use the sparse registry protocol for Cargo.
[registries.crates-io]
protocol = "sparse"
12 changes: 7 additions & 5 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3

- name: Install Protoc
uses: arduino/setup-protoc@v1
with:
Expand All @@ -23,7 +23,7 @@ jobs:
rustup toolchain install stable --profile minimal --no-self-update
rustup default stable
- name: Rust Cache
- name: Rust Cache
uses: Swatinem/rust-cache@v2

- name: Build
Expand All @@ -40,12 +40,14 @@ jobs:
run: cargo clippy

- name: Style
# Only run on Ubuntu
if: ${{ matrix.os == 'ubuntu-latest' }}
run: cargo fmt --all -- --check

- name: Test
if: ${{ matrix.os == 'ubuntu-latest' }}
run: cargo test
# Don't run on Windows because Unix sockets are not available.
if: ${{ matrix.os != 'windows-latest' }}
run: cargo test

concurrency:
cancel-in-progress: true
Expand Down
17 changes: 15 additions & 2 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ jobs:
artifact_name: deltio
asset_name: deltio-${{ needs.tag.outputs.tag }}-linux-aarch64
install_linker: gcc-aarch64-linux-gnu

- target: aarch64-unknown-linux-musl
os: ubuntu-latest
artifact_name: deltio
asset_name: deltio-${{ needs.tag.outputs.tag }}-linux-musl-aarch64
install_linker: aarch64-linux-musl-cross

- target: armv7-unknown-linux-gnueabihf
os: ubuntu-latest
Expand Down Expand Up @@ -162,8 +168,15 @@ jobs:
- name: Install Cross-Platform Linker
if: ${{ matrix.install_linker }}
run: |
sudo apt-get update
sudo apt-get install -y ${{ matrix.install_linker }}
# Special instructions for installing the aarch64 linker for musl
if [ "${{ matrix.install_linker }}" = "aarch64-linux-musl-cross" ]; then
wget -P ~ https://musl.cc/aarch64-linux-musl-cross.tgz
tar -xvf ~/aarch64-linux-musl-cross.tgz -C "${HOME}"
echo "${HOME}/aarch64-linux-musl-cross/bin" >> $GITHUB_PATH
else
sudo apt-get update
sudo apt-get install -y ${{ matrix.install_linker }}
fi
- name: Install Protoc
uses: arduino/setup-protoc@v1
Expand Down
30 changes: 25 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 6 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "deltio"
version = "0.2.0"
version = "0.3.0"
edition = "2021"
authors = ["Jeff Hansen"]
description = "A Google Cloud Pub/Sub emulator alternative for local testing and CI"
Expand All @@ -25,6 +25,11 @@ env_logger = "0.10.0"
lazy_static = "1.4.0"
clap = { version = "4.2.7", features = ["derive"] }

# MiMalloc does not currently cross-compile for `i686-unknown-linux-musl` target,
# so we'll disable MiMalloc for x86 Linux for now.
[target.'cfg(not(all(target_arch = "x86", target_os = "linux")))'.dependencies]
mimalloc = { version = "0.1.37", default-features = false }

[dev-dependencies]
uuid = { version = "1.3.0", features = ["v4", "fast-rng"] }
tokio = { version = "1.28.0", features = ["full", "test-util"] }
Expand Down
34 changes: 21 additions & 13 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ WORKDIR /deltio

# The target platform we are compiling for.
# Populated by BuildX
ARG BUILDPLATFORM
ARG TARGETPLATFORM

# The build platform we are compiling on.
# Populated by BuildX
ARG BUILDPLATFORM

# Install the required cross-compiler toolchain based on the target platform.
# Basically, if the target platform is ARM, then we'll need
# the `gcc-arm-linux-gnueabihf` linker, otherwise we'll need
Expand All @@ -31,21 +34,27 @@ RUN <<EOF
echo "Target platform: $TARGETPLATFORM"
apt-get update
if [ "$TARGETPLATFORM" = "linux/arm64" ]; then
apt-get install -y gcc-aarch64-linux-gnu
rustup target add aarch64-unknown-linux-gnu
echo -n "aarch64-unknown-linux-gnu" > .target
# musl-cross isn't available via apt-get, so have to download and install it manually.
mkdir /opt/musl-cross
wget -P /opt/musl-cross https://musl.cc/aarch64-linux-musl-cross.tgz
tar -xvf /opt/musl-cross/aarch64-linux-musl-cross.tgz -C "/opt/musl-cross"
rustup target add aarch64-unknown-linux-musl
echo -n "aarch64-unknown-linux-musl" > .target
else
apt-get install -y gcc-multilib
apt-get install -y musl-tools
if [ "$TARGETPLATFORM" = "linux/amd64" ]; then
rustup target add x86_64-unknown-linux-gnu
echo -n "x86_64-unknown-linux-gnu" > .target
rustup target add x86_64-unknown-linux-musl
echo -n "x86_64-unknown-linux-musl" > .target
elif [ "$TARGETPLATFORM" = "linux/386" ]; then
rustup target add i686-unknown-linux-gnu
echo -n "i686-unknown-linux-gnu" > .target
rustup target add i686-unknown-linux-musl
echo -n "i686-unknown-linux-musl" > .target
fi
fi
EOF

# In case we installed the musl-cross tools, add it to the path.
ENV PATH="/opt/musl-cross/aarch64-linux-musl-cross/bin:${PATH}"

# Copy manifests.
COPY ./.cargo/config.toml ./.cargo/config.toml
COPY ./Cargo.lock ./Cargo.lock
Expand All @@ -56,7 +65,7 @@ RUN <<EOF
set -e;

# If the build platform is the same as the target platform, we don't
# to use any target.
# need to use any target.
if [ "$BUILDPLATFORM" = "$TARGETPLATFORM" ]; then
cargo build --release
rm ./target/release/deps/deltio*
Expand All @@ -79,7 +88,7 @@ COPY ./src ./src
RUN <<EOF
set -e;
# If the build platform is the same as the target platform, we don't
# to use any target.
# need to use any target.
if [ "$BUILDPLATFORM" = "$TARGETPLATFORM" ]; then
cargo build --release
exit 0
Expand All @@ -91,7 +100,7 @@ RUN <<EOF
EOF

# Our final base image.
FROM --platform=$TARGETPLATFORM debian:buster-slim as deltio
FROM --platform=$TARGETPLATFORM scratch as deltio

# Copy the build artifact from the build stage
COPY --from=build /deltio/target/release/deltio .
Expand All @@ -100,5 +109,4 @@ COPY --from=build /deltio/target/release/deltio .
EXPOSE 8085

# Set the startup command to run the binary.
ENV RUST_LOG=info
CMD ["./deltio", "--bind", "0.0.0.0:8085"]
31 changes: 6 additions & 25 deletions src/collections/messages.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,21 @@
use crate::topics::{MessageId, TopicMessage};
use std::collections::{HashMap, VecDeque};
use crate::topics::TopicMessage;
use std::collections::VecDeque;
use std::sync::Arc;

/// Maintains a list of messages that can be enumerated in insertion order
/// as well as looked up by ID.
/// Maintains a list of messages that can be enumerated in insertion order.
pub struct Messages {
/// The message list.
///
/// This is implemented as a `VecDeque` because we will be
/// iterating and popping from the front.
pub list: VecDeque<Arc<TopicMessage>>,

/// The map of messages.
/// Used for retrieving a message by ID.
/// TODO: Remove if this is not used.
pub map: HashMap<MessageId, Arc<TopicMessage>>,
}

impl Messages {
/// Creates a new `Messages`.
pub fn new() -> Self {
Self {
list: VecDeque::new(),
map: HashMap::new(),
}
}

Expand All @@ -32,12 +25,8 @@ impl Messages {

// Attempt to reserve the additional capacity needed.
let size_hint = iter.size_hint().0;
self.map.reserve(size_hint);
self.list.reserve(size_hint);
self.list.extend(iter.map(|m| {
self.map.insert(m.id, Arc::clone(&m));
m
}));
self.list.extend(iter);
}

/// Returns the amount of messages contained within
Expand All @@ -52,23 +41,19 @@ impl Messages {

/// Removes a message from the front of the queue.
pub fn pop_front(&mut self) -> Option<Arc<TopicMessage>> {
self.list.pop_front().map(|message| {
// Also remove it from the map.
self.map.remove(&message.id);
message
})
self.list.pop_front()
}

/// Clears all the messages.
pub fn clear(&mut self) {
self.map.clear();
self.list.clear();
}
}

#[cfg(test)]
mod tests {
use super::*;
use crate::topics::MessageId;

#[test]
fn append_adds_messages_to_list_and_map() {
Expand All @@ -86,13 +71,9 @@ mod tests {
assert_eq!(messages.len(), 2);

assert_eq!(messages.list.len(), 2);
assert_eq!(messages.map.len(), 2);

assert_eq!(messages.list[0].data[0], 0);
assert_eq!(messages.list[1].data[0], 1);

assert_eq!(messages.list[0].id, messages.map[&ids[0]].id);
assert_eq!(messages.list[1].id, messages.map[&ids[1]].id);
}

#[test]
Expand Down
9 changes: 9 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ use std::sync::Arc;
use tonic::transport::server::Router;
use tonic::transport::Server;

#[cfg(not(all(target_arch = "x86", target_os = "linux")))]
use mimalloc::MiMalloc;

#[cfg(not(all(target_arch = "x86", target_os = "linux")))]
// Use MiMalloc as the global allocator for supported targets.
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;

/// Creates a server builder configured with the Pub/Sub gRPC services.
pub fn make_server_builder() -> Router {
let topic_manager = Arc::new(TopicManager::new());
let subscription_manager = Arc::new(SubscriptionManager::new());
Expand Down
Loading

0 comments on commit a7859fd

Please sign in to comment.