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

Refactor for easier deploys of new versions. Make 5.1.0 default #19

Closed
wants to merge 30 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
71b72bc
Upgrade to jemalloc 5.0.0
mojodna Jun 15, 2017
8fcccc9
Point to compiled binary
mojodna Jun 15, 2017
fe5463f
Fix binary filename
nateberkopec Oct 3, 2017
2c76718
Reorganize and update README for jemalloc 5
nateberkopec Oct 3, 2017
066c82e
Add CHANGELOG
nateberkopec Oct 3, 2017
48a8c80
Prevent leading/trailing colons in path variables
brian-kephart Jun 3, 2017
81173ed
Rewrite build system for new versions and Heroku stacks
gaffneyc Dec 4, 2017
375363c
Remove linking env variables
gaffneyc Dec 5, 2017
6b234c7
Refactor out vendor function
gaffneyc Dec 5, 2017
308e06c
Adds JEMALLOC_ENABLED config option
gaffneyc Dec 5, 2017
34b32dc
Adds JEMALLOC_VERSION config option
gaffneyc Dec 5, 2017
b349587
Switch to releases on gaffneyc/heroku-buildpack-jemalloc
gaffneyc Dec 5, 2017
6a412c0
Switch to bzip from gzip
gaffneyc Dec 5, 2017
f3e7022
Update documentation to point to this fork
gaffneyc Dec 5, 2017
f17748b
Update link to jemalloc's site
gaffneyc Dec 5, 2017
6564f30
Switch to using symlink to jemalloc in LD_PRELOAD
gaffneyc Dec 8, 2017
6306663
Update the readme to better discuss configuration
gaffneyc Dec 8, 2017
950fce9
Fixes note about Cedar being deprecated
gaffneyc Dec 11, 2017
375e64a
Adds list of available versions to the README
gaffneyc Jan 18, 2018
2a700b3
Fix error when JEMALLOC_ENABLED is not set
gaffneyc Feb 13, 2018
bae11b1
Add builds for the latest of each recent minor version
gaffneyc Apr 27, 2018
28198d9
Adds initial builds for the Heroku-18 stack
gaffneyc Apr 27, 2018
65508d3
Rewrites the description to talk more about what jemalloc is
gaffneyc May 9, 2018
67a1585
Adds build of 5.1.0 to `make all`
gaffneyc May 9, 2018
dfd4a11
Switch to bzip2 best compression for builds
gaffneyc May 9, 2018
baaf2b7
Removes static libs and include files from the buildpack
gaffneyc May 9, 2018
08f77c0
Remove docker images after building
gaffneyc Aug 22, 2018
872b03c
Make 5.1.0 the default
gaffneyc Aug 22, 2018
a30679b
Merge branch 'master' into refactor_build_for_easy_updates
bf4 Sep 3, 2018
2c18bfa
Replace gaffneyc with mojodna
bf4 Sep 3, 2018
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## 5.0.0

* Update to jemalloc 5
* LD_PRELOAD now works differently. Previously, you could point it directly to the jemalloc shared library (/app/vendor/jemalloc/lib/libjemalloc.so.1). Now, it's better to let jemalloc do it for you, as noted in the README. You must change this environment variable when upgrading and it is not backwards compatible. If you are not using LD_PRELOAD and instead use jemalloc.sh, no action is required.
11 changes: 0 additions & 11 deletions Dockerfile

This file was deleted.

46 changes: 33 additions & 13 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,21 +1,41 @@
default: dist/jemalloc-4.2.1-1.tar.gz
default: cedar-14 heroku-16 heroku-18

dist/jemalloc-4.2.1-1.tar.gz: jemalloc-cedar
docker cp $<:/tmp/jemalloc-cedar.tar.gz .
mkdir -p $$(dirname $@)
mv jemalloc-cedar.tar.gz $@
VERSION := 5.1.0
ROOT_DIR := $(shell dirname $(abspath $(lastword $(MAKEFILE_LIST))))

clean:
rm -rf src/ dist/
-docker rm jemalloc-cedar

src/jemalloc.tar.bz2:
# Download missing source archives to ./src/
src/jemalloc-%.tar.bz2:
mkdir -p $$(dirname $@)
curl -sL https://github.com/jemalloc/jemalloc/releases/download/4.2.1/jemalloc-4.2.1.tar.bz2 -o $@
curl -fsL https://github.com/jemalloc/jemalloc/releases/download/$*/jemalloc-$*.tar.bz2 -o $@

.PHONY: cedar-14 heroku-16 heroku-18

# Build for cedar-14 stack
cedar-14: src/jemalloc-$(VERSION).tar.bz2
docker run --rm -it --volume="$(ROOT_DIR):/wrk" \
heroku/cedar:14 /wrk/build.sh $(VERSION) cedar-14

# Build for heroku-16 stack
heroku-16: src/jemalloc-$(VERSION).tar.bz2
docker run --rm -it --volume="$(ROOT_DIR):/wrk" \
heroku/heroku:16-build /wrk/build.sh $(VERSION) heroku-16

.PHONY: jemalloc-cedar
# Build for heroku-18 stack
heroku-18: src/jemalloc-$(VERSION).tar.bz2
docker run --rm -it --volume="$(ROOT_DIR):/wrk" \
heroku/heroku:18-build /wrk/build.sh $(VERSION) heroku-18

jemalloc-cedar: src/jemalloc.tar.bz2
docker build --rm -t mojodna/$@ .
-docker rm $@
docker run --name $@ mojodna/$@ /bin/echo $@
# Build recent releases for all supported stacks
all:
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=3.6.0
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.0.4
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.1.1
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.2.1
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.3.1
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.4.0
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=4.5.0
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=5.0.1
$(MAKE) cedar-14 heroku-16 heroku-18 VERSION=5.1.0
104 changes: 83 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,47 +1,109 @@
# heroku-buildpack-jemalloc

I am a Heroku buildpack that installs
[jemalloc](http://www.canonware.com/jemalloc/) into a dyno slug.
[jemalloc](http://jemalloc.net/) is a general purpose malloc implementation
that works to avoid memory fragmentation in multithreaded applications. This
buildpack makes it easy to install and use jemalloc on Heroku and compatible
platforms.

## Using
## Install

To use jemalloc with your app, either prefix commands with `jemalloc.sh <cmd>`
or set `LD_PRELOAD=/app/vendor/jemalloc/lib/libjemalloc.so.1` in your
environment (it will then apply to all commands run).
```console
heroku buildpacks:add --index 1 https://github.com/mojodna/heroku-buildpack-jemalloc.git
git push heroku master
```

Example, in your Procfile:
## Usage

### Recommended

Set the JEMALLOC_ENABLED config option to true and jemalloc will be used for
all commands run inside of your dynos.

```console
heroku config:set JEMALLOC_ENABLED=true
```

### Per dyno

To control when jemalloc is configured on a per dyno basis use
`jemalloc.sh <cmd>` and ensure that JEMALLOC_ENABLED is unset.

Example Procfile:
```yaml
web: jemalloc.sh bundle exec puma -C config/puma.rb
```

Setting LD_PRELOAD can sometimes mess with the building of an app - if you're seeing errors during slug compilation, try removing LD_PRELOAD and just using `jemalloc.sh`.
## Configuration

### Composed
### JEMALLOC_ENABLED

[Heroku now supports using multiple buildpacks for an app](https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app).
Set this to true to automatically enable jemalloc.

```bash
heroku buildpacks:add --index 1 https://github.com/mojodna/heroku-buildpack-jemalloc.git
git push heroku master
```console
heroku config:set JEMALLOC_ENABLED=true
```

If you're not seeing great results from Jemalloc 4.x, you can try Jemalloc 3.6 instead:
To disable jemalloc set the option to false. This will cause the application to
restart disabling jemalloc.

```bash
heroku buildpacks:add --index 1 https://github.com/mojodna/heroku-buildpack-jemalloc.git#v3.6.0
git push heroku master
```console
heroku config:set JEMALLOC_ENABLED=false
```

Note that you can also use this syntax to lock your buildpack to a specific release.
### JEMALLOC_VERSION

Set this to select or pin to a specific version of jemalloc. The default is to
use the latest stable version if this is not set. You will receive an error
mentioning tar if the version does not exist.

**Default**: `5.1.0`

**note:** This setting is only used during slug compilation. Changing it will
require a code change to be deployed in order to take affect.

```console
heroku config:set JEMALLOC_VERSION=3.6.0
```

#### Available Versions

| Version |
| ------- |
| 3.6.0 |
| 4.0.4 |
| 4.1.1 |
| 4.2.1 |
| 4.3.1 |
| 4.4.0 |
| 4.5.0 |
| 5.0.1 |
| 5.1.0 |
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

probably shouldn't be merged unless this is acurrate


The complete and most up to date list of supported versions and stacks is
available on the [releases page.](https://github.com/mojodna/heroku-buildpack-jemalloc/releases)

## Building

This uses Docker to build against Heroku
[stack-image](https://github.com/heroku/stack-images)-like images.

```bash
make
```console
make VERSION=5.1.0
```

Artifacts will be dropped in `dist/`. See `Dockerfile`s for build options.
Artifacts will be dropped in `dist/` based on Heroku stack and jemalloc version.

### Deploying New Versions

- `make VERSION=X.Y.Z`
- `open dist`
- Go to [releases](https://github.com/mojodna/heroku-buildpack-jemalloc/releases)
- Edit the release corresponding to each heroku Stack
- Drag and drop the new build to attach

### Creating a New Stack
- Go to [releases](https://github.com/mojodna/heroku-buildpack-jemalloc/releases)
- Click "Draft a new release"
- Tag is the name of the Stack (e.g. `heroku-18`)
- Target is `release-master`
- Title is `Builds for the [stack] stack`
81 changes: 29 additions & 52 deletions bin/compile
Original file line number Diff line number Diff line change
@@ -1,61 +1,38 @@
#!/usr/bin/env bash
# bin/compile <build-dir> <cache-dir>
# bin/compile <build-dir> <cache-dir> <env-dir>
set -e

set -e # fail fast

# parse params
# Parse params
BUILD_DIR=$1
CACHE_DIR=$2
BUILDPACK_NAME=jemalloc

function indent() {
c='s/^/ /'
case $(uname) in
Darwin) sed -l "$c";;
*) sed -u "$c";;
esac
}

function vendor() {
binary="$1"
path="$2"

echo "Fetching $binary" | indent
mkdir -p $path
curl -sL $binary -s -o - | tar xz -C $path -f -

[ -d "$path/bin" ] && export PATH=$path/bin:$PATH
export CPPPATH="$path/include:$CPPPATH"
export CPATH="$path/include:$CPATH"
export LIBRARY_PATH="$path/lib:$LIBRARY_PATH"
export LD_LIBRARY_PATH="$path/lib:$LD_LIBRARY_PATH"
[ -d "$path/lib/pkgconfig" ] && export PKG_CONFIG_PATH="$path/lib/pkgconfig:$PKG_CONFIG_PATH"

true
}

echo "-----> Vendoring binaries"
vendor "https://github.com/mojodna/heroku-buildpack-jemalloc/releases/download/4.2.1/jemalloc-4.2.1-1.tar.gz" "$BUILD_DIR/vendor/jemalloc"

echo "-----> Configuring build environment"

cat <<EOF > export
export PATH="$PATH:\$PATH"
export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:$LD_LIBRARY_PATH"
export LIBRARY_PATH="\$LIBRARY_PATH:$LIBRARY_PATH"
export PKG_CONFIG_PATH="\$PKG_CONFIG_PATH:$PKG_CONFIG_PATH"
export CPPPATH="\$CPPPATH:$CPPPATH"
export CPATH="\$CPATH:$CPATH"
EOF
ENV_DIR=$3

# Default version
version="5.1.0"

# Read version from configured JEMALLOC_VERSION
if [ -f $ENV_DIR/JEMALLOC_VERSION ]; then
version=$(cat $ENV_DIR/JEMALLOC_VERSION)
fi

url="https://github.com/mojodna/heroku-buildpack-jemalloc/releases/download/$STACK/jemalloc-$version.tar.bz2"
dest="$BUILD_DIR/vendor/jemalloc"

echo "-----> Vendoring jemalloc $version"
echo " Fetching $url"

mkdir -p $dest
curl -sL $url | tar -C $dest -xj

echo "-----> Building runtime environment"
mkdir -p $BUILD_DIR/.profile.d

cat <<EOF > $BUILD_DIR/.profile.d/$BUILDPACK_NAME.sh
export PATH="${PATH//$BUILD_DIR//app}:\$PATH"
export LD_LIBRARY_PATH="\$LD_LIBRARY_PATH:${LD_LIBRARY_PATH//$BUILD_DIR//app}"
export LIBRARY_PATH="\$LIBRARY_PATH:${LIBRARY_PATH//$BUILD_DIR//app}"
export PKG_CONFIG_PATH="\$PKG_CONFIG_PATH:${PKG_CONFIG_PATH//$BUILD_DIR//app}"
export CPPPATH="\$CPPPATH:${CPPPATH//$BUILD_DIR//app}"
export CPATH="\$CPATH:${CPATH//$BUILD_DIR//app}"
cat <<'EOF' > $BUILD_DIR/.profile.d/jemalloc.sh
export PATH="$PATH:/app/vendor/jemalloc/bin"

# Configure LD_PRELOAD when JEMALLOC_ENABLED is set to "true". Setting this can
# be tricky for people and it occasionally changes with new versions.
if [ "$JEMALLOC_ENABLED" = 'true' ]; then
export LD_PRELOAD="/app/vendor/jemalloc/lib/libjemalloc.so $LD_PRELOAD"
fi
EOF
17 changes: 17 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/bin/bash
# usage: build [version] [stack]
set -e

version=$1
stack=$2
build=`mktemp -d`

tar -C $build --strip-components=1 -xj -f /wrk/src/jemalloc-$version.tar.bz2

cd $build
./configure --prefix=/app/vendor/jemalloc
make -j $(nproc --all) install_bin install_lib_shared

# Bundle and compress the compiled library
mkdir -p /wrk/dist/$stack
tar -C /app/vendor/jemalloc -c . | bzip2 -9 > /wrk/dist/$stack/jemalloc-$version.tar.bz2