DevHeads.net

Postings by Samuel Williams

async & async-io 1.0.0

Hello Friends,

I recently released async and async-io v1.0.0

<a href="https://github.com/socketry/async" title="https://github.com/socketry/async">https://github.com/socketry/async</a>
<a href="https://github.com/socketry/async-io" title="https://github.com/socketry/async-io">https://github.com/socketry/async-io</a>

- These gems provide zero-overhead syntax for asynchronous IO.
- Servers run inside a reactor task which can be started and stopped
deterministically.
- Very low overhead per IO operation.
- Scales to multiple CPU cores using containers
(<a href="https://github.com/socketry/async-container" title="https://github.com/socketry/async-container">https://github.com/socketry/async-container</a>)
- Easy standardised testing using <a href="https://github.com/socketry/async-rspec" title="https://github.com/socketry/async-rspec">https://github.com/socketry/async-rspec</a>

As already mentioned, there is DNS server available:
<a href="https://github.com/socketry/async-dns" title="https://github.com/socketry/async-dns">https://github.com/socketry/async-dns</a> and also a rack

RubyDNS 2.0.0 released.

RubyDNS provides a Ruby DSL for making a DNS server. It's trivial, for
example, to hook up DNS TXT requests to Wikipedia.

This release builds on several new gems for asynchronous IO including:

- async 1.0.0 (asynchronous events/timers using the reactor pattern & fibers)
- async-io 1.0.0
- async-dns 1.0.0

RubyDNS 1.x was built on top of Celluloid, while RubyDNS 2.0 is built
on top the above gems. With the utmost admiration and respect:
Celluloid's design made it hard to use in practice.

async-http -> falcon

I've quickly hacked together a rack compliant server using async-http
called falcon

<a href="https://github.com/socketry/falcon" title="https://github.com/socketry/falcon">https://github.com/socketry/falcon</a>

It's completely alpha, but may be of interest to some who have been
following this.

Feel free to have a hack at it if it's something you are interested
in. It's currently using a multi-threaded model but it's simple to
choose another.

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

async-http vs puma

I've got a local rack app which is a simple disk/file based wiki with
no caching whatsoever.

async-http hits 100,000 req/s

I've been working on a stack of gems (async, async-io and async-http)
as a proof of concept that Ruby can do fast async networking similar
to Node - and perhaps even better in some cases.

I have finally got async-http to the point where, as a
proof-of-concept, I think it's validated at least part of the above
statement.

<a href="https://github.com/socketry/async" title="https://github.com/socketry/async">https://github.com/socketry/async</a>
<a href="https://github.com/socketry/async-io" title="https://github.com/socketry/async-io">https://github.com/socketry/async-io</a>
<a href="https://github.com/socketry/async-http" title="https://github.com/socketry/async-http">https://github.com/socketry/async-http</a>

On my desktop, I can get a nominal throughput of between 30,000 req/s
to 100,000 req/s with 4 cores/8 processes.

cloudflare (API) && cloudflare-dns-update gems

I've just released updated versions of these two gems.

cloudflare provides a RestClient::Resource based API for accessing Cloudflare.

On top of that I've built cloudflare-dns-update which uses tty-prompt
and samovar for an interactive command-line. It's pretty cool - video
here: <a href="https://github.com/ioquatix/cloudflare-dns-update" title="https://github.com/ioquatix/cloudflare-dns-update">https://github.com/ioquatix/cloudflare-dns-update</a>

Kind regards,
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Testing gem dependencies

I am working on a gem rb-inotify (let's call A from now on) which is a
dependency of listen (call B).

B depends on A.

A doesn't have many specs right now, behaviour is defined primarily by
correct functioning of B which has a lot of specs.

I want to run specs on travis for A (it has a few and we would add
more in the future), but I also want to run all of the specs for B
too.

Before i have a go trying to make this work, does anyone have any
ideas/suggestions?

Thanks
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailma

build-dependency and build-uri

Build::Dependency is a dependency resolution algorithm. It's primarily
used in Teapot, primarily a C++ build tool (but it's completely
generic). However, I've decided to extract it, because I've also been
using it in a tool for deploying Arch Linux virtual machines. In this
case, it reads the PKGBUILD files and can construct a dependency
graph. It doesn't support versioned constraints (although it probably
could) as they are not useful in teapot.

rubyworks/facets

Hi Everyone,

I've been slowly trying to improve facets

<a href="https://github.com/rubyworks/facets" title="https://github.com/rubyworks/facets">https://github.com/rubyworks/facets</a>

It's a pretty awesome gem, but it also needs a lot of work.

I was wondering if anyone else would be willing to help with the next release.

The goal for 4.0 is to really be a 2.1+ release, with all
functionality removed which is either a/ already supported natively by
ruby or b/ obscure to the point of being incorrect.

Kind regards,
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

RubyDNS 2.0.0-rc1

Hi Everyone,

Perhaps this is a bit premature but I'm pretty excited to be updating RubyDNS.

<a href="https://github.com/ioquatix/rubydns" title="https://github.com/ioquatix/rubydns">https://github.com/ioquatix/rubydns</a>

In order to get to this point, I built a new asynchronous IO framework for Ruby:

<a href="https://github.com/socketry/async" title="https://github.com/socketry/async">https://github.com/socketry/async</a>

`Async::Reactor` implements the reactor pattern and basically takes
all the good parts of `celluloid-io`.

Utopia - a rack based web framework

Hi Everyone,

I've just released the next major version of Utopia, source available
at <a href="https://github.com/ioquatix/utopia" title="https://github.com/ioquatix/utopia">https://github.com/ioquatix/utopia</a>

It's a content-centric web framework for Ruby. It's fast (native ragel
parsers) multi-threaded (concurrent-ruby for internal caches,
rack-freeze for safety) and it's used in production for several years
now.

Gem with native C for MRI, pure ruby fallback, how to compile?

Hi,

I can't seem to figure out how this is supposed to work.

Here is my extconf.rb which is currently working:

<a href="https://github.com/ioquatix/trenni/blob/master/ext/trenni/extconf.rb" title="https://github.com/ioquatix/trenni/blob/master/ext/trenni/extconf.rb">https://github.com/ioquatix/trenni/blob/master/ext/trenni/extconf.rb</a>

But, I'm afraid it's a huge hack.

How is this supposed to work?

I should build package. On MRI, when installing, it should compile C
extension.

String capacity

If I know that a string is going to be at least X bytes in my native
extension, is there some way to set the initial capacity to avoid
memory allocations?

I see rb_str_tmp_new but I can't do that with an encoding.. could I just use

VALUE str = rb_str_tmp_new(X);
rb_enc_associate(str, enc);

Thanks
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

rb_str_new with custom subclass of rb_cString

Is it possible to construct a string with a custom subclass or replace the
klass pointer of a VALUE in an existing one?

I see rb_str_new_with_class but it actually takes an object and uses its
class rather than a class directly which might work but is a bit of a hack.
Ideally would be able to change the class of the object... but perhaps
that's asking too much?

Thanks,
Samuel

ffi-clang for Ruby

Hi Everyone,

After the release of LLVM 4.0, I wanted to get the Ruby FFI gem
updated and working. It's been a long time since it's last gem
release.

It can do some pretty awesome things (obviously most credit goes to
LLVM).

Merging multiple aliases files together

I don't know the best way to achieve this.

I have some "user" packages which install various users on a linux
system. I want the setup to be entirely automated, and as part of this
I want to set up some mail aliases for each user, and add their alias
to the root alias. Essentially, the following represents one user:

root: bob
bob: <a href="mailto: ... at example dot com"> ... at example dot com</a>

I have 0 or more of these user packages, and I want to, some how,
merge all these aliases together.

Best way to call Integer on temporary?

I like to use Float, Integer and String to typecast data from user. It
raises an exception if the value was invalid for some reason.

However, it doesn't easily support optional values, e.g. Integer(nil)
fails too. So, I end up writing code like:

result = (tmp = x[:foo]) ? Integer(tmp) : nil

But that seems really ugly.

Is there a better way without just writing my own wrapper all the
time?

Best way to handle Integer/Bignum/Fixnum

Hello,

In my code, after migrating to 2.4.0, I see a lot of

gems/mapping-1.0.0/lib/mapping/object_model.rb:26: warning: constant
::Fixnum is deprecated
gems/mapping-1.0.0/lib/mapping/object_model.rb:26: warning: constant
::Bignum is deprecated

This code still works okay, but I was wondering, how should I write my
code now to not produce warnings with both 2.3 and 2.4?

e.g.

Relaxo - git backed database with lightweight trasactional API

Hello Friends.

I recently published Relaxo 1.0. It's a document storage engine
written on top of libgit2/rugged.

<a href="https://github.com/ioquatix/relaxo" title="https://github.com/ioquatix/relaxo">https://github.com/ioquatix/relaxo</a>

Relaxo exposes the underlying data model of git deliberately. It's
essentially a persistent data structure with algorithms implemented in
C. The relaxo gem is only ~150 lines of code. It's standing on the
shoulders of giants.

The nice thing about libgit2 is that it has some provisions for a
backend storage other than a file-system.

Trenni - a gem for fast templating and parsing

Hello.

I've recently finished implementing upgrades to Trenni:
<a href="https://github.com/ioquatix/trenni" title="https://github.com/ioquatix/trenni">https://github.com/ioquatix/trenni</a>

It now includes C parsers generated by Ragel to improve both
performance and correctness.

It's faster than Nokogiri and ERB which was exciting.

We use this in production from today and it reduces latency by up to
50% for some pages compared to previous StringScanner/Regex parser.

rb_funcall and explicit method cache

I'm implementing some code that calls the same method multiple times
from C. I'd like to cache the method to avoid costly method lookup. Is
this possible?

Something like

METHOD * m = rb_method_lookup(object, rb_intern("doit"));
rb_invoke(m, args...)

Is any such thing possible?

Thanks
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

String.new what is default encoding?

Hello.

When preparing for immutable strings by default, I changed my code from

buffer = ""

to

buffer = String.new

However, an unintended side effect of this was the encoding:

2.3.1 :001 > "".encoding
=> #<Encoding:UTF-8>
2.3.1 :002 > String.new.encoding
=> #<Encoding:ASCII-8BIT>

I'm replacing `""` with `String.new(encoding: Encoding::UTF_8)` but
wondering what exactly is the best practice here going forward?

Kind regards,
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Is it possible to make your own String Encoding?

I'd like to define an encoding which is a derivative of UTF-8 but
includes HTML entities.

Is this possible? I don't see anything like Encoding.new, for example.

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

URI#absolute?

Hi..

I feel like this should work.

$ URI.parse("/base/uri") + URI.parse("relative")
URI::BadURIError: both URI are relative

The result should be URI with path = "/base/relative".

What do you think? Is this a bug? Or is it designed like this on purpose?

Kind regards,
Samuel

Unsubscribe: <mailto:ruby-talk-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-talk>

Substitute one gem for another in Gemfile?

I'm developing a gem with an idea to replace an existing gem which I don't
control. The replacement gem provides a compatible API.

For my own project, of course I can just switch the gem i the Gemfile. But,
what about other gems which depend on the original gem that I want to
replace?

Is it possible to say - this gem dependency will now be provided by some
other gem?

~> operator

Hello.

I sometimes write code in irb/pry and I want to send the result into
another function.

Something like

Foo.bar(baz)

Then, it turns out I wanted to write

f(Foo.bar(baz))

So I have to move the cursor all the way to the left and insert f and
perhaps some more brackets, etc.

I was wondering if we can discuss some new operator, like following:

a ~> b
defined as b(a)

Some other languages already have such an operator.

Ideas? Discussion?

Makes my life easier:

Foo.bar(baz) ~> f

It could be called the "goes into" operator.

Fingerprint - general purpose data integrity tool.

Fingerprint is a general purpose data integrity tool that uses
cryptographic hashes to detect changes in files. Fingerprint scans a
directory tree and generates a small transcript file containing the names
and hashes of the files. This snapshot file can then be used to generate a
list of files that have been created, deleted, or modified.

Best way to make sub-hash from hash with specific keys.

I have a a function which looks like this:

def rename(basename: true, extension: '.txt') ...

I have a configuration hash, e.g.

config = {basename: false, extension: '.pdf', offset: 10, something:
'else'}

I want to call the function:

rename(**config)

but clearly this doesn't work because some arguments are specified, e.g.
:offset which are not included in the function.

Flopp - FLexible OPtion Parser

Hi,

Just made a new fun gem for implementing command line parsers.

<a href="https://github.com/ioquatix/flopp" title="https://github.com/ioquatix/flopp">https://github.com/ioquatix/flopp</a>

It's designed to make it easy to generate decent command-lines while
supporting a wide range of parsing requirements (e.g. ARGV splits "--").

Please do let me know if you use it in a project so I can link to it. Yes,
the documentation is a bit crappy right now, I will work on that, feel free
to submit a PR too :)

Kind regards,
Samuel

trenni-markdown - a literate programming markdown parser and generator

I've been writing a bit of C++ code lately and been thinking about how to
document it.

Obviously, a lot of documentation generators generate documentation by
looking at the source code and extracting comments.

But after some discussion with a friend, we wondered if it was possible to
generate code from documentation, e.g.