Giter Site home page Giter Site logo

socketry / lightio Goto Github PK

View Code? Open in Web Editor NEW
163.0 9.0 6.0 197 KB

LightIO is a userland implemented green thread library for ruby

License: MIT License

Ruby 99.91% Shell 0.09%
ruby networking concurrency io eventloop fiber multithreading async thread green

lightio's Introduction

LightIO

Gem Version Build Status Coverage Status MIT licensed Gitter

LightIO provides green thread to ruby. Like Golang's goroutine, or Crystal's fiber. In LightIO it is called beam.

Example:

require 'lightio'

start = Time.now

beams = 1000.times.map do
  # LightIO::Beam is green-thread, use it instead Thread
  LightIO::Beam.new do
    # do some io operations in beam
    LightIO.sleep(1)
  end
end

beams.each(&:join)
seconds = Time.now - start
puts "1000 beams take #{seconds - 1} seconds to create"

LightIO ship ruby stdlib compatible library under LightIO or LightIO::Library namespace, these libraries provide the ability to schedule LightIO beams when IO operations occur.

LightIO also provide a monkey patch, it replaces ruby Thread with LightIO::Thread, and also replaces IO related classes.

Example:

require 'lightio'
# apply monkey patch at beginning
LightIO::Monkey.patch_all!

require 'net/http'

host = 'github.com'
port = 443

start = Time.now

10.times.map do
  Thread.new do
    Net::HTTP.start(host, port, use_ssl: true) do |http|
      res = http.request_get('/ping')
      p res.code
    end
  end
end.each(&:join)

puts "#{Time.now - start} seconds"

See Examples for detail.

You Should Know

In fact ruby core team already plan to implement Thread::Green in core language, see https://bugs.ruby-lang.org/issues/13618

It means if ruby implemented Thread::Green, this library has no reason to exist. But as a crazy userland implemented green thread library, it bring lots of fun to me, so I will continue to maintain it, and welcome to use.

See Wiki and Roadmap to get more information.

LightIO is build upon nio4r. Get heavily inspired by gevent, async-io.

Installation

Add this line to your application's Gemfile:

gem 'lightio'

And then execute:

$ bundle

Or install it yourself as:

$ gem install lightio

Documentation

Please see LightIO Wiki for more information.

The following documentations is also usable:

Discussion

https://groups.google.com/group/lightio

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake spec to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/jjyr/lightio. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the Contributor Covenant code of conduct.

License

The gem is available as open source under the terms of the MIT License.

Copyright, 2017-2018, by Jiang Jinyang

Code of Conduct

Everyone interacting in the Lightio project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.

lightio's People

Contributors

ayrat555 avatar dependabot[bot] avatar enummela avatar ioquatix avatar jjyr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lightio's Issues

Compatible with Ruby 2.5 or higher?

Is this Ruby 2.5 friendly... I am getting initialization errors from the kernel for require.
I also noticed that I cant install the other gems, b/c hitimes is not compatible with Ruby 2.5.

README.md Typos

While reading about this project I found a few typos in the README. I made a PR with some fixes: #11.
This is an interesting project, cheers!

`fiber called across stack rewinding barrier` error in rails console

I've added lightio to my Gemfile, started rails console and tried to execute the simple example

Running via Spring preloader in process 10594
Loading development environment (Rails 5.2.2)
irb(main):001:0> result = []
=> []
irb(main):002:0> b1 = LightIO::Beam.new {result << 1}
=> #<LightIO::Core::Beam:0x0000557fd27d0b48@/home/username/.asdf/installs/ruby/2.5.3/lib/ruby/gems/2.5.0/gems/lightio-0.4.4/lib/lightio/core/beam.rb:49 (created)>
irb(main):003:0> b2 = LightIO::Beam.new {result << 2}
=> #<LightIO::Core::Beam:0x0000557fd27f8440@/home/username/.asdf/installs/ruby/2.5.3/lib/ruby/gems/2.5.0/gems/lightio-0.4.4/lib/lightio/core/beam.rb:49 (created)>
irb(main):004:0> b1.join
Traceback (most recent call last):
        1: from (irb):4
FiberError (fiber called across stack rewinding barrier)
irb(main):005:0> 

Do I need to use Soba project with rails in order to execute this code in the rails console?

`FFI::TypeDefs` will missing some types if require `ffi` after monkey patch

On my macbook:

require 'ffi' then monkey patch:

 => {:void=>#<FFI::Type::Builtin:VOID size=1 alignment=1>, :bool=>#<FFI::Type::Builtin:BOOL size=1 alignment=1>, :string=>#<FFI::Type::Builtin:STRING size=8 alignment=8>, :char=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :uchar=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :short=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :ushort=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :int=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :uint=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :long=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :ulong=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :long_long=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :ulong_long=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :float=>#<FFI::Type::Builtin:FLOAT32 size=4 alignment=4>, :double=>#<FFI::Type::Builtin:FLOAT64 size=8 alignment=8>, :long_double=>#<FFI::Type::Builtin:LONGDOUBLE size=16 alignment=16>, :pointer=>#<FFI::Type::Builtin:POINTER size=8 alignment=8>, :int8=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :uint8=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :int16=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :uint16=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :int32=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :uint32=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :int64=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :uint64=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :buffer_in=>#<FFI::Type::Builtin:BUFFER_IN size=8 alignment=8>, :buffer_out=>#<FFI::Type::Builtin:BUFFER_OUT size=8 alignment=8>, :buffer_inout=>#<FFI::Type::Builtin:BUFFER_INOUT size=8 alignment=8>, :varargs=>#<FFI::Type::Builtin:VARARGS size=1 alignment=1>, FFI::StrPtrConverter=>#<FFI::Type::Mapped:0x007fdf7f6ba520 size=8 alignment=8>, :strptr=>#<FFI::Type::Mapped:0x007fdf7f6ba520 size=8 alignment=8>, :__int8_t=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :__uint8_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :__int16_t=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :__uint16_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :__int32_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__uint32_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__int64_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :__uint64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :__darwin_intptr_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :__darwin_natural_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_ct_rune_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_ptrdiff_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :__darwin_size_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :__darwin_wchar_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_rune_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_wint_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_clock_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :__darwin_socklen_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_ssize_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :__darwin_time_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :int8_t=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :int16_t=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :int32_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :int64_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :u_int8_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :u_int16_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :u_int32_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :u_int64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :register_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :intptr_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :uintptr_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :user_addr_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :user_size_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :user_ssize_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :user_long_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :user_ulong_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :user_time_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :user_off_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :syscall_arg_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :__darwin_blkcnt_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :__darwin_blksize_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_dev_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_fsblkcnt_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_fsfilcnt_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_gid_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_id_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_ino64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :__darwin_ino_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :__darwin_mach_port_name_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_mach_port_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_mode_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :__darwin_off_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :__darwin_pid_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_sigset_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_suseconds_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :__darwin_uid_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :__darwin_useconds_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :"__darwin_uuid_t[16]"=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :"__darwin_uuid_string_t[37]"=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :__darwin_pthread_key_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :u_char=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :u_short=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :u_int=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :u_long=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :u_quad_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :quad_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :qaddr_t=>#<FFI::Type::Builtin:POINTER size=8 alignment=8>, :caddr_t=>#<FFI::Type::Builtin:POINTER size=8 alignment=8>, :daddr_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :dev_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :fixpt_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :blkcnt_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :blksize_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :gid_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :in_addr_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :in_port_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :ino_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :ino64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :key_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :mode_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :nlink_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :id_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :pid_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :off_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :segsz_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :swblk_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :uid_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :clock_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :size_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :ssize_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :time_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :useconds_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :suseconds_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :rsize_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :errno_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :fd_mask=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :pthread_key_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :fsblkcnt_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :fsfilcnt_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :sa_family_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :socklen_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :uint8_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :uint16_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :uint32_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :uint64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :int_least8_t=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :int_least16_t=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :int_least32_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :int_least64_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :uint_least8_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :uint_least16_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :uint_least32_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :uint_least64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :int_fast8_t=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :int_fast16_t=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :int_fast32_t=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :int_fast64_t=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :uint_fast8_t=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :uint_fast16_t=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :uint_fast32_t=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :uint_fast64_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :intmax_t=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :uintmax_t=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :rlim_t=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>} 

require 'ffi' after monkey patch(missing some types):

 => {:void=>#<FFI::Type::Builtin:VOID size=1 alignment=1>, :bool=>#<FFI::Type::Builtin:BOOL size=1 alignment=1>, :string=>#<FFI::Type::Builtin:STRING size=8 alignment=8>, :char=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :uchar=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :short=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :ushort=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :int=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :uint=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :long=>#<FFI::Type::Builtin:LONG size=8 alignment=8>, :ulong=>#<FFI::Type::Builtin:ULONG size=8 alignment=8>, :long_long=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :ulong_long=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :float=>#<FFI::Type::Builtin:FLOAT32 size=4 alignment=4>, :double=>#<FFI::Type::Builtin:FLOAT64 size=8 alignment=8>, :long_double=>#<FFI::Type::Builtin:LONGDOUBLE size=16 alignment=16>, :pointer=>#<FFI::Type::Builtin:POINTER size=8 alignment=8>, :int8=>#<FFI::Type::Builtin:INT8 size=1 alignment=1>, :uint8=>#<FFI::Type::Builtin:UINT8 size=1 alignment=1>, :int16=>#<FFI::Type::Builtin:INT16 size=2 alignment=2>, :uint16=>#<FFI::Type::Builtin:UINT16 size=2 alignment=2>, :int32=>#<FFI::Type::Builtin:INT32 size=4 alignment=4>, :uint32=>#<FFI::Type::Builtin:UINT32 size=4 alignment=4>, :int64=>#<FFI::Type::Builtin:INT64 size=8 alignment=8>, :uint64=>#<FFI::Type::Builtin:UINT64 size=8 alignment=8>, :buffer_in=>#<FFI::Type::Builtin:BUFFER_IN size=8 alignment=8>, :buffer_out=>#<FFI::Type::Builtin:BUFFER_OUT size=8 alignment=8>, :buffer_inout=>#<FFI::Type::Builtin:BUFFER_INOUT size=8 alignment=8>, :varargs=>#<FFI::Type::Builtin:VARARGS size=1 alignment=1>, FFI::StrPtrConverter=>#<FFI::Type::Mapped:0x007fa1158376f0 size=8 alignment=8>, :strptr=>#<FFI::Type::Mapped:0x007fa1158376f0 size=8 alignment=8>, :caddr_t=>#<FFI::Type::Builtin:POINTER size=8 alignment=8>} 

[Question] Windows supported?

  • OS: WInsows 10
  • Ruby: 2.5.5 x32

It fails after require 'lightio', error messages are shown below:

ArgumentError: unsupported backend:
from C:/Ruby25/lib/ruby/gems/2.5.0/gems/nio4r-2.3.1/lib/nio/selector.rb:17:in `initialize'
Caused by LoadError: cannot load such file -- lightio
from C:/Ruby25/lib/ruby/2.5.0/rubygems/core_ext/kernel_require.rb:59:in `require'

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.