Git Product home page Git Product logo

stan.rb's Introduction

NATS Streaming Ruby Client

WARNING: Product reached end of life ⚠️

NATS Streaming reached its end of life.

It is no longer supported and has been replaced by Jetstream

JetStream is build into the NATS Server and supported by all major clients. Check examples here

stan.rb's People

Contributors

dependabot[bot] avatar gcolliso avatar jarema avatar stephenprater avatar wallyqs avatar

Stargazers

 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  avatar  avatar  avatar  avatar

stan.rb's Issues

Cannot connect again if previously closed connection

Hello @wallyqs ,

we've found an issue regarding client connection/disconnection. The simplest use case to recreate is to follow these steps:

sc = STAN::Client.new
sc.connect("cluster", "client-123", nats: { servers: ["nats://nats:4222"] })
sc.close
sc.connect("cluster", "client-123", nats: { servers: ["nats://nats:4222"] })
NATS::IO::Timeout: nats: timeout
from /bundle_cache/gems/nats-pure-0.5.0/lib/nats/io/client.rb:794:in `with_nats_timeout'

Full exception trace:

 0: /bundle_cache/gems/nats-pure-0.5.0/lib/nats/io/client.rb:794:in `with_nats_timeout'
 1: /bundle_cache/gems/nats-pure-0.5.0/lib/nats/io/client.rb:510:in `block in flush'
 2: /usr/local/lib/ruby/2.3.0/monitor.rb:214:in `mon_synchronize'
 3: /bundle_cache/gems/nats-pure-0.5.0/lib/nats/io/client.rb:504:in `flush'
 4: /bundle_cache/gems/nats-streaming-0.2.2/lib/stan/client.rb:141:in `connect'

Am I doing something wrong?

Messages are not delivered to one of subscribers

Few days ago one of client apps using Ruby client stopped seeing new messages on its subscription. E.g. messages got published fine both by other clients and this one. According to Nats streaming stats (available on port 8222) everything looks fine. However one of Ruby clients does not receive it, like there were no incoming messages.
I've suspected RAFT logs might be corrupt, so I've reinstalled NATS streaming from scratch. But the error persists.

I'm using a cluster of NATS Streaming servers of the latest version (0.22.1). Using latest version of Ruby client (0.2.2). Subscribe to messages from specified date in the past. Subscription is not durable. Tried enabling "deliver_all_available" option, but still got no messages.

Any ideas what should I do? How to debug the issue?

Basic usage from readme doesn't work

$ ~/Downloads/nats-streaming-server-v0.3.6-darwin-amd64/nats-streaming-server-v0.3.6 -D -V
[88396] 2016/12/29 20:29:04.077635 [INF] Starting nats-streaming-server[test-cluster] version 0.3.6
[88396] 2016/12/29 20:29:04.077964 [INF] Starting nats-server version 0.9.6
[88396] 2016/12/29 20:29:04.077970 [DBG] Go build version go1.7.4
[88396] 2016/12/29 20:29:04.077977 [INF] Listening for client connections on 0.0.0.0:4222
[88396] 2016/12/29 20:29:04.078056 [DBG] Server id is 1tvBmxDprDfhHWAyvOzkXn
[88396] 2016/12/29 20:29:04.078061 [INF] Server is ready
[88396] 2016/12/29 20:29:04.105546 [DBG] 127.0.0.1:51365 - cid:1 - Client connection created
[88396] 2016/12/29 20:29:04.105803 [TRC] 127.0.0.1:51365 - cid:1 - ->> [CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"_NSS-test-cluster-send","lang":"go","version":"1.2.2","protocol":1}]
[88396] 2016/12/29 20:29:04.105843 [TRC] 127.0.0.1:51365 - cid:1 - ->> [PING]
[88396] 2016/12/29 20:29:04.105847 [TRC] 127.0.0.1:51365 - cid:1 - <<- [PONG]
[88396] 2016/12/29 20:29:04.106085 [DBG] 127.0.0.1:51366 - cid:2 - Client connection created
[88396] 2016/12/29 20:29:04.106272 [TRC] 127.0.0.1:51366 - cid:2 - ->> [CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"_NSS-test-cluster-general","lang":"go","version":"1.2.2","protocol":1}]
[88396] 2016/12/29 20:29:04.106315 [TRC] 127.0.0.1:51366 - cid:2 - ->> [PING]
[88396] 2016/12/29 20:29:04.106323 [TRC] 127.0.0.1:51366 - cid:2 - <<- [PONG]
[88396] 2016/12/29 20:29:04.106482 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _INBOX.j2UwoevbQUieAvFAEeDGYz  1]
[88396] 2016/12/29 20:29:04.106506 [TRC] 127.0.0.1:51366 - cid:2 - ->> [UNSUB 1 1]
[88396] 2016/12/29 20:29:04.106514 [DBG] 127.0.0.1:51366 - cid:2 - Deferring actual UNSUB(_INBOX.j2UwoevbQUieAvFAEeDGYz): 1 max, 0 received
[88396] 2016/12/29 20:29:04.106522 [TRC] 127.0.0.1:51366 - cid:2 - ->> [PUB _STAN.discover.test-cluster _INBOX.j2UwoevbQUieAvFAEeDGYz 45]
[88396] 2016/12/29 20:29:04.106534 [TRC] 127.0.0.1:51366 - cid:2 - ->> MSG_PAYLOAD: [

test-cluster_INBOX.j2UwoevbQUieAvFAEeDGTl]
[88396] 2016/12/29 20:29:04.357731 [TRC] 127.0.0.1:51366 - cid:2 - ->> [UNSUB 1 ]
[88396] 2016/12/29 20:29:04.357756 [TRC] 127.0.0.1:51366 - cid:2 - <-> [DELSUB 1]
[88396] 2016/12/29 20:29:04.358486 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.discover.test-cluster  2]
[88396] 2016/12/29 20:29:04.358525 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.pub.j2UwoevbQUieAvFAEeDG3d.>  3]
[88396] 2016/12/29 20:29:04.358545 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.sub.j2UwoevbQUieAvFAEeDG8r  4]
[88396] 2016/12/29 20:29:04.358556 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.unsub.j2UwoevbQUieAvFAEeDGJJ  5]
[88396] 2016/12/29 20:29:04.358585 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.subclose.j2UwoevbQUieAvFAEeDGE5  6]
[88396] 2016/12/29 20:29:04.358692 [TRC] 127.0.0.1:51366 - cid:2 - ->> [SUB _STAN.close.j2UwoevbQUieAvFAEeDGOX  7]
[88396] 2016/12/29 20:29:04.358709 [TRC] 127.0.0.1:51366 - cid:2 - ->> [PING]
[88396] 2016/12/29 20:29:04.358714 [TRC] 127.0.0.1:51366 - cid:2 - <<- [PONG]
[88396] 2016/12/29 20:29:04.358801 [INF] STAN: Message store is MEMORY
[88396] 2016/12/29 20:29:04.358812 [INF] STAN: --------- Store Limits ---------
[88396] 2016/12/29 20:29:04.358822 [INF] STAN: Channels:                  100 *
[88396] 2016/12/29 20:29:04.358826 [INF] STAN: -------- channels limits -------
[88396] 2016/12/29 20:29:04.358831 [INF] STAN:   Subscriptions:          1000 *
[88396] 2016/12/29 20:29:04.358835 [INF] STAN:   Messages     :       1000000 *
[88396] 2016/12/29 20:29:04.358855 [INF] STAN:   Bytes        :     976.56 MB *
[88396] 2016/12/29 20:29:04.358860 [INF] STAN:   Age          :     unlimited *
[88396] 2016/12/29 20:29:04.358863 [INF] STAN: --------------------------------

Then copying and pasting the example into a console:

NATS::IO::Timeout: nats: timeout

telnet 127.0.0.1 4222 works fine.

Manual ACKs are not being sent

Hi there,

I have multiple event channels and I'm processing each new event in a separate thread, and using manual ACKs in order to notify NATS whenever the event processing is done.
But sometimes, when I restart the server, I see it starts to process events that I know were already processed before.

Sample code for the reference:

    channels.each do |channel|
      subscriptions << client.subscribe(channel,
        queue: queue_group,
        durable_name: durable_name,
        max_inflight: MAX_INFLIGHT,
        manual_acks: true) do |msg|
          process_event(msg)
      end
    end

# ...

 def process_event(msg)
    Thread.new do
      event_service.process(msg)
    rescue StandardError => e
      logger.error e.message
    ensure
      client.ack(msg)
    end
  end

# ...

  def init_nats_client
    @client = STAN::Client.new
    @nats = NATS::IO::Client.new
    @nats.on_reconnect do
      logger.info("NATS reconnected")
    end
    @nats.on_disconnect do |reason|
      logger.error("NATS disconnected: #{reason}")
    end
    @nats.on_error do |error|
      logger.error("NATS error: #{error}")
    end
  end

# ...

  def connect
    nats.connect({ servers: [server],
                   reconnect_time_wait: DEFAULT_TIMEOUT,
                   max_reconnect_attempts: -1,
                   reconnect: true,
                   ping_interval: PING_INTERVAL })
    client.connect(cluster_id, client_id, nats: nats)
    logger.info("NATS connected")
  rescue StandardError => e
    logger.error "NATS client connect error: #{e.message}"
  end

Handle disconnections

Hello!

There's no way to handle disconnections between the server and the client, and I saw a ConnectionLostHandler in the Go client. Is there a plan to implement this functionality in the Ruby client too?

Incorrect handling of UTF8 messages

Hi,

the problem:

when you try to send a message with any UTF8 character, it fails

actual result:

it raises with:

/bundle_cache/gems/nats-streaming-0.2.2/lib/stan/client.rb:193:in `initialize': U+0100 from UTF-8 to ASCII-8BIT (Encoding::UndefinedConversionError)                            
        from /bundle_cache/gems/nats-streaming-0.2.2/lib/stan/client.rb:193:in `new'                                                                                            
        from /bundle_cache/gems/nats-streaming-0.2.2/lib/stan/client.rb:193:in `publish'

As stated here, using #b on message string resolves the problem.

Can't connect

Hi, for some reason I can't connect to the NATS streaming server.

I've launched both NATS server and streaming server locally via Docker:

docker run -p 4222:4222 -ti nats:latest
docker run -p 4223:4223 -p 8223:8223 nats-streaming -p 4223 -m 8223

Then I tried to connect to it like this:

require 'stan/client'

opts = { servers: ["nats://127.0.0.1:4222"] }
sc = STAN::Client.new
sc.connect("test-cluster", "client-pub", nats: opts)

But I always get STAN::ConnectReqTimeoutError (stan: failed connecting to 'test-cluster').

I tried publishing messages through nats-pure interface and it works fine. I also tried running Go examples from https://github.com/nats-io/stan.go/tree/master/examples and it also worked.

It seems to me like NATS streaming server API has changed since the last commit (or something of this sort), so this gem no longer works. I hope I am wrong, but please let me know if that's the case.

Nats option "token" cannot be passed to Nats client

Hi, thank you for great product.

This doesn't works:

opts = {
  servers: ['tls://example.com:4222'],
  token: 'mytoken',
}

STAN::Client.new.connect("test-cluster", "client-123", nats: opts)

Current workaround is to include token to URI. This works.

opts = {
  servers: ['tls://[email protected]:4222'],
}

STAN::Client.new.connect("test-cluster", "client-123", nats: opts)

I saw https://github.com/nats-io/stan.rb/blob/master/lib/stan/client.rb#L135 and seems to work if the options are passed to NATS client.

I also read the document and couldn't find how to connect to NATS streaming server using token, as connection options are different from NATS.start options described here.
https://nats-io.github.io/docs/developer/security/token.html

Can I pass the { token: 'something' } as NATS client options?
If not, I think it is helpful to add document how to connect NATS streaming server using token.

Thank you,

nats-streaming throws segmentation fault on ruby-alpine

When using the nats-streaming gem (0.2.2) on a ruby-alpine image (e.g. the ruby:2.7-alpinedocker image), a segmentation fault is thrown when publishing a message, to nats-streaming running in a seperate container with the nats-streaming:0.18.0-alpine image.
This is consistently occuring on several ruby:2.x -alpine versions (everything works as expected on the non-alpine ruby images)

The following can be used to reproduce the issue:

require 'stan/client'

stan = STAN::Client.new
nats = NATS::IO::Client.new
nats.connect(servers: ["nats://nats:4222"])
stan.connect("nats-dev-cluster", "test", nats: nats)
stan.publish("test", "test")

Executing this script will immediately fail and logs the following:

/usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb:157: [BUG] Segmentation fault at 0x0000000000010666
ruby 2.7.1p83 (2020-03-31 revision a0c7c23c9c) [x86_64-linux-musl]

-- Control frame information -----------------------------------------------
c:0004 p:---- s:0024 e:000023 CFUNC  :decode
c:0003 p:0480 s:0019 E:000a08 METHOD /usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb:157
c:0002 p:0063 s:0008 E:0025c0 EVAL   test.rb:7 [FINISH]
c:0001 p:0000 s:0003 E:001090 (none) [FINISH]

-- Ruby level backtrace information ----------------------------------------
test.rb:7:in `<main>'
/usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb:157:in `connect'
/usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb:157:in `decode'

-- Machine register context ------------------------------------------------
 RIP: 0x0000000000010666 RBP: 0x00007ffc12409110 RSP: 0x00007ffc124090b8
 RAX: 0x000000000000000a RBX: 0x000000000000000a RCX: 0x0000000000000008
 RDX: 0x0000000000000001 RDI: 0x00007ffc124090c8 RSI: 0x00007ffc124090d0
  R8: 0x0000000000000007  R9: 0x000055d5a19e22a0 R10: 0x0000000000000000
 R11: 0x00000000ffffffff R12: 0x000055d5a19e1fc0 R13: 0x0000000000000000
 R14: 0x00007ffc12409170 R15: 0x000055d5a19e1fc0 EFL: 0x0000000000010246

-- Other runtime information -----------------------------------------------

* Loaded script: test.rb

* Loaded features:

    0 enumerator.so
    1 thread.rb
    2 rational.so
    3 complex.so
    4 ruby2_keywords.rb
    5 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
    6 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
    7 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/rbconfig.rb
    8 /usr/local/lib/ruby/2.7.0/rubygems/compatibility.rb
    9 /usr/local/lib/ruby/2.7.0/rubygems/defaults.rb
   10 /usr/local/lib/ruby/2.7.0/rubygems/deprecate.rb
   11 /usr/local/lib/ruby/2.7.0/rubygems/errors.rb
   12 /usr/local/lib/ruby/2.7.0/rubygems/version.rb
   13 /usr/local/lib/ruby/2.7.0/rubygems/requirement.rb
   14 /usr/local/lib/ruby/2.7.0/rubygems/platform.rb
   15 /usr/local/lib/ruby/2.7.0/rubygems/basic_specification.rb
   16 /usr/local/lib/ruby/2.7.0/rubygems/stub_specification.rb
   17 /usr/local/lib/ruby/2.7.0/rubygems/util.rb
   18 /usr/local/lib/ruby/2.7.0/rubygems/text.rb
   19 /usr/local/lib/ruby/2.7.0/rubygems/user_interaction.rb
   20 /usr/local/lib/ruby/2.7.0/rubygems/specification_policy.rb
   21 /usr/local/lib/ruby/2.7.0/rubygems/util/list.rb
   22 /usr/local/lib/ruby/2.7.0/rubygems/specification.rb
   23 /usr/local/lib/ruby/2.7.0/rubygems/exceptions.rb
   24 /usr/local/lib/ruby/2.7.0/rubygems/bundler_version_finder.rb
   25 /usr/local/lib/ruby/2.7.0/rubygems/dependency.rb
   26 /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_gem.rb
   27 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
   28 /usr/local/lib/ruby/2.7.0/monitor.rb
   29 /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_require.rb
   30 /usr/local/lib/ruby/2.7.0/rubygems/core_ext/kernel_warn.rb
   31 /usr/local/lib/ruby/2.7.0/rubygems.rb
   32 /usr/local/lib/ruby/2.7.0/rubygems/path_support.rb
   33 /usr/local/lib/ruby/2.7.0/did_you_mean/version.rb
   34 /usr/local/lib/ruby/2.7.0/did_you_mean/core_ext/name_error.rb
   35 /usr/local/lib/ruby/2.7.0/did_you_mean/levenshtein.rb
   36 /usr/local/lib/ruby/2.7.0/did_you_mean/jaro_winkler.rb
   37 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checker.rb
   38 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers/class_name_checker.rb
   39 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers/variable_name_checker.rb
   40 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/name_error_checkers.rb
   41 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/method_name_checker.rb
   42 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/key_error_checker.rb
   43 /usr/local/lib/ruby/2.7.0/did_you_mean/spell_checkers/null_checker.rb
   44 /usr/local/lib/ruby/2.7.0/did_you_mean/formatters/plain_formatter.rb
   45 /usr/local/lib/ruby/2.7.0/did_you_mean/tree_spell_checker.rb
   46 /usr/local/lib/ruby/2.7.0/did_you_mean.rb
   47 /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/protobuf/message_exts.rb
   48 /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/2.7/protobuf_c.so
   49 /usr/local/lib/ruby/2.7.0/forwardable/impl.rb
   50 /usr/local/lib/ruby/2.7.0/forwardable/version.rb
   51 /usr/local/lib/ruby/2.7.0/forwardable.rb
   52 /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/protobuf/repeated_field.rb
   53 /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/protobuf.rb
   54 /usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/pb/protocol.pb.rb
   55 /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/io/parser.rb
   56 /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/io/version.rb
   57 /usr/local/lib/ruby/2.7.0/securerandom.rb
   58 /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/nuid.rb
   59 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
   60 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
   61 /usr/local/lib/ruby/2.7.0/socket.rb
   62 /usr/local/lib/ruby/2.7.0/json/version.rb
   63 /usr/local/lib/ruby/2.7.0/ostruct/version.rb
   64 /usr/local/lib/ruby/2.7.0/ostruct.rb
   65 /usr/local/lib/ruby/2.7.0/json/generic_object.rb
   66 /usr/local/lib/ruby/2.7.0/json/common.rb
   67 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
   68 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
   69 /usr/local/lib/ruby/2.7.0/json/ext.rb
   70 /usr/local/lib/ruby/2.7.0/json.rb
   71 /usr/local/lib/ruby/2.7.0/uri/version.rb
   72 /usr/local/lib/ruby/2.7.0/uri/rfc2396_parser.rb
   73 /usr/local/lib/ruby/2.7.0/uri/rfc3986_parser.rb
   74 /usr/local/lib/ruby/2.7.0/uri/common.rb
   75 /usr/local/lib/ruby/2.7.0/uri/generic.rb
   76 /usr/local/lib/ruby/2.7.0/uri/file.rb
   77 /usr/local/lib/ruby/2.7.0/uri/ftp.rb
   78 /usr/local/lib/ruby/2.7.0/uri/http.rb
   79 /usr/local/lib/ruby/2.7.0/uri/https.rb
   80 /usr/local/lib/ruby/2.7.0/uri/ldap.rb
   81 /usr/local/lib/ruby/2.7.0/uri/ldaps.rb
   82 /usr/local/lib/ruby/2.7.0/uri/mailto.rb
   83 /usr/local/lib/ruby/2.7.0/uri.rb
   84 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
   85 /usr/local/lib/ruby/2.7.0/digest.rb
   86 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
   87 /usr/local/lib/ruby/2.7.0/openssl/bn.rb
   88 /usr/local/lib/ruby/2.7.0/openssl/pkey.rb
   89 /usr/local/lib/ruby/2.7.0/openssl/cipher.rb
   90 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
   91 /usr/local/lib/ruby/2.7.0/openssl/config.rb
   92 /usr/local/lib/ruby/2.7.0/openssl/digest.rb
   93 /usr/local/lib/ruby/2.7.0/openssl/x509.rb
   94 /usr/local/lib/ruby/2.7.0/openssl/buffering.rb
   95 /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
   96 /usr/local/lib/ruby/2.7.0/ipaddr.rb
   97 /usr/local/lib/ruby/2.7.0/openssl/ssl.rb
   98 /usr/local/lib/ruby/2.7.0/openssl/pkcs5.rb
   99 /usr/local/lib/ruby/2.7.0/openssl.rb
  100 /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/io/client.rb
  101 /usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/version.rb
  102 /usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb

* Process memory map:

55d5a0be3000-55d5a0be4000 r--p 00000000 fd:03 40786510                   /usr/local/bin/ruby
55d5a0be4000-55d5a0be5000 r-xp 00001000 fd:03 40786510                   /usr/local/bin/ruby
55d5a0be5000-55d5a0be6000 r--p 00002000 fd:03 40786510                   /usr/local/bin/ruby
55d5a0be6000-55d5a0be7000 r--p 00002000 fd:03 40786510                   /usr/local/bin/ruby
55d5a0be7000-55d5a0be8000 rw-p 00003000 fd:03 40786510                   /usr/local/bin/ruby
55d5a10eb000-55d5a19e6000 rw-p 00000000 00:00 0                          [heap]
7f5cba169000-7f5cba16b000 ---p 00000000 00:00 0
7f5cba16b000-7f5cba36c000 rw-p 00000000 00:00 0
7f5cba36c000-7f5cba36e000 ---p 00000000 00:00 0
7f5cba36e000-7f5cba56f000 rw-p 00000000 00:00 0
7f5cba56f000-7f5cba571000 ---p 00000000 00:00 0
7f5cba571000-7f5cba772000 rw-p 00000000 00:00 0
7f5cba772000-7f5cba774000 ---p 00000000 00:00 0
7f5cba774000-7f5cba975000 rw-p 00000000 00:00 0
7f5cba975000-7f5cba977000 ---p 00000000 00:00 0
7f5cba977000-7f5cbab78000 rw-p 00000000 00:00 0
7f5cbab78000-7f5cbab7a000 ---p 00000000 00:00 0
7f5cbab7a000-7f5cbad7b000 rw-p 00000000 00:00 0
7f5cbad7b000-7f5cbad7c000 r--p 00000000 fd:03 73121043                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
7f5cbad7c000-7f5cbad7d000 r-xp 00001000 fd:03 73121043                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
7f5cbad7d000-7f5cbad7e000 r--p 00002000 fd:03 73121043                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
7f5cbad7e000-7f5cbad7f000 r--p 00002000 fd:03 73121043                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
7f5cbad7f000-7f5cbad80000 rw-p 00003000 fd:03 73121043                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/nonblock.so
7f5cbad80000-7f5cbad82000 r--p 00000000 fd:03 40787005                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
7f5cbad82000-7f5cbad88000 r-xp 00002000 fd:03 40787005                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
7f5cbad88000-7f5cbad8a000 r--p 00008000 fd:03 40787005                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
7f5cbad8a000-7f5cbad8b000 r--p 00009000 fd:03 40787005                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
7f5cbad8b000-7f5cbad8c000 rw-p 0000a000 fd:03 40787005                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/stringio.so
7f5cbad8c000-7f5cbad8e000 r--p 00000000 fd:03 40786963                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
7f5cbad8e000-7f5cbad90000 r-xp 00002000 fd:03 40786963                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
7f5cbad90000-7f5cbad91000 r--p 00004000 fd:03 40786963                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
7f5cbad91000-7f5cbad92000 r--p 00004000 fd:03 40786963                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
7f5cbad92000-7f5cbad93000 rw-p 00005000 fd:03 40786963                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/digest.so
7f5cbad93000-7f5cbae08000 r--p 00000000 fd:03 70454464                   /lib/libcrypto.so.1.1
7f5cbae08000-7f5cbaf5d000 r-xp 00075000 fd:03 70454464                   /lib/libcrypto.so.1.1
7f5cbaf5d000-7f5cbafe1000 r--p 001ca000 fd:03 70454464                   /lib/libcrypto.so.1.1
7f5cbafe1000-7f5cbb00c000 r--p 0024d000 fd:03 70454464                   /lib/libcrypto.so.1.1
7f5cbb00c000-7f5cbb00e000 rw-p 00278000 fd:03 70454464                   /lib/libcrypto.so.1.1
7f5cbb00e000-7f5cbb012000 rw-p 00000000 00:00 0
7f5cbb012000-7f5cbb02e000 r--p 00000000 fd:03 70454490                   /lib/libssl.so.1.1
7f5cbb02e000-7f5cbb06e000 r-xp 0001c000 fd:03 70454490                   /lib/libssl.so.1.1
7f5cbb06e000-7f5cbb086000 r--p 0005c000 fd:03 70454490                   /lib/libssl.so.1.1
7f5cbb086000-7f5cbb08f000 r--p 00073000 fd:03 70454490                   /lib/libssl.so.1.1
7f5cbb08f000-7f5cbb093000 rw-p 0007c000 fd:03 70454490                   /lib/libssl.so.1.1
7f5cbb093000-7f5cbb0a7000 r--p 00000000 fd:03 40786994                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
7f5cbb0a7000-7f5cbb0dc000 r-xp 00014000 fd:03 40786994                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
7f5cbb0dc000-7f5cbb0ec000 r--p 00049000 fd:03 40786994                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
7f5cbb0ec000-7f5cbb0f0000 r--p 00058000 fd:03 40786994                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
7f5cbb0f0000-7f5cbb0f1000 rw-p 0005c000 fd:03 40786994                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/openssl.so
7f5cbb0f1000-7f5cbb0f3000 r--p 00000000 fd:03 17528145                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
7f5cbb0f3000-7f5cbb0fa000 r-xp 00002000 fd:03 17528145                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
7f5cbb0fa000-7f5cbb0fc000 r--p 00009000 fd:03 17528145                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
7f5cbb0fc000-7f5cbb0fd000 r--p 0000a000 fd:03 17528145                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
7f5cbb0fd000-7f5cbb0fe000 rw-p 0000b000 fd:03 17528145                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/generator.so
7f5cbb0fe000-7f5cbb100000 r--p 00000000 fd:03 17611616                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
7f5cbb100000-7f5cbb104000 r-xp 00002000 fd:03 17611616                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
7f5cbb104000-7f5cbb106000 r--p 00006000 fd:03 17611616                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
7f5cbb106000-7f5cbb107000 r--p 00007000 fd:03 17611616                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
7f5cbb107000-7f5cbb108000 rw-p 00008000 fd:03 17611616                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/json/ext/parser.so
7f5cbb108000-7f5cbb109000 r--p 00000000 fd:03 73121044                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
7f5cbb109000-7f5cbb10a000 r-xp 00001000 fd:03 73121044                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
7f5cbb10a000-7f5cbb10b000 r--p 00002000 fd:03 73121044                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
7f5cbb10b000-7f5cbb10c000 r--p 00002000 fd:03 73121044                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
7f5cbb10c000-7f5cbb10d000 rw-p 00003000 fd:03 73121044                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/io/wait.so
7f5cbb10d000-7f5cbb113000 r--p 00000000 fd:03 40787004                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
7f5cbb113000-7f5cbb134000 r-xp 00006000 fd:03 40787004                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
7f5cbb134000-7f5cbb13c000 r--p 00027000 fd:03 40787004                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
7f5cbb13c000-7f5cbb13d000 r--p 0002e000 fd:03 40787004                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
7f5cbb13d000-7f5cbb13e000 rw-p 0002f000 fd:03 40787004                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/socket.so
7f5cbb13e000-7f5cbb392000 r-xp 00000000 fd:03 41444580                   /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/2.7/protobuf_c.so
7f5cbb392000-7f5cbb394000 r--p 00054000 fd:03 41444580                   /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/2.7/protobuf_c.so
7f5cbb394000-7f5cbb396000 rw-p 00056000 fd:03 41444580                   /usr/local/bundle/gems/google-protobuf-3.12.2-x86_64-linux/lib/google/2.7/protobuf_c.so
7f5cbb396000-7f5cbb397000 r--p 00000000 fd:03 40786991                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
7f5cbb397000-7f5cbb398000 r-xp 00001000 fd:03 40786991                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
7f5cbb398000-7f5cbb399000 r--p 00002000 fd:03 40786991                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
7f5cbb399000-7f5cbb39a000 r--p 00002000 fd:03 40786991                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
7f5cbb39a000-7f5cbb39b000 rw-p 00003000 fd:03 40786991                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/monitor.so
7f5cbb39b000-7f5cbb39c000 r--p 00000000 fd:03 40786983                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
7f5cbb39c000-7f5cbb39e000 r-xp 00001000 fd:03 40786983                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
7f5cbb39e000-7f5cbb39f000 r--p 00003000 fd:03 40786983                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
7f5cbb39f000-7f5cbb3a0000 r--p 00003000 fd:03 40786983                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
7f5cbb3a0000-7f5cbb3a1000 rw-p 00004000 fd:03 40786983                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/trans/transdb.so
7f5cbb3a1000-7f5cbb3a2000 r--p 00000000 fd:03 17611516                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
7f5cbb3a2000-7f5cbb3a3000 r-xp 00001000 fd:03 17611516                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
7f5cbb3a3000-7f5cbb3a4000 r--p 00002000 fd:03 17611516                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
7f5cbb3a4000-7f5cbb3a5000 r--p 00002000 fd:03 17611516                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
7f5cbb3a5000-7f5cbb3a6000 rw-p 00003000 fd:03 17611516                   /usr/local/lib/ruby/2.7.0/x86_64-linux-musl/enc/encdb.so
7f5cbb3a6000-7f5cbb3a7000 ---p 00000000 00:00 0
7f5cbb3a7000-7f5cbb448000 rw-p 00000000 00:00 0
7f5cbb448000-7f5cbb449000 ---p 00000000 00:00 0
7f5cbb449000-7f5cbb4ea000 rw-p 00000000 00:00 0
7f5cbb4ea000-7f5cbb4eb000 ---p 00000000 00:00 0
7f5cbb4eb000-7f5cbb58c000 rw-p 00000000 00:00 0
7f5cbb58c000-7f5cbb58d000 ---p 00000000 00:00 0
7f5cbb58d000-7f5cbb62e000 rw-p 00000000 00:00 0
7f5cbb62e000-7f5cbb62f000 ---p 00000000 00:00 0
7f5cbb62f000-7f5cbb6d0000 rw-p 00000000 00:00 0
7f5cbb6d0000-7f5cbb6d1000 ---p 00000000 00:00 0
7f5cbb6d1000-7f5cbb772000 rw-p 00000000 00:00 0
7f5cbb772000-7f5cbb773000 ---p 00000000 00:00 0
7f5cbb773000-7f5cbb814000 rw-p 00000000 00:00 0
7f5cbb814000-7f5cbb815000 ---p 00000000 00:00 0
7f5cbb815000-7f5cbb8b6000 rw-p 00000000 00:00 0
7f5cbb8b6000-7f5cbb8b7000 ---p 00000000 00:00 0
7f5cbb8b7000-7f5cbb958000 rw-p 00000000 00:00 0
7f5cbb958000-7f5cbb959000 ---p 00000000 00:00 0
7f5cbb959000-7f5cbb9fa000 rw-p 00000000 00:00 0
7f5cbb9fa000-7f5cbb9fb000 ---p 00000000 00:00 0
7f5cbb9fb000-7f5cbba9c000 rw-p 00000000 00:00 0
7f5cbba9c000-7f5cbba9d000 ---p 00000000 00:00 0
7f5cbba9d000-7f5cbbb3e000 rw-p 00000000 00:00 0
7f5cbbb3e000-7f5cbbb3f000 ---p 00000000 00:00 0
7f5cbbb3f000-7f5cbbbe0000 rw-p 00000000 00:00 0
7f5cbbbe0000-7f5cbbbe1000 ---p 00000000 00:00 0
7f5cbbbe1000-7f5cbbc82000 rw-p 00000000 00:00 0
7f5cbbc82000-7f5cbbc83000 ---p 00000000 00:00 0
7f5cbbc83000-7f5cbbd24000 rw-p 00000000 00:00 0
7f5cbbd24000-7f5cbbd25000 ---p 00000000 00:00 0
7f5cbbd25000-7f5cbbdc6000 rw-p 00000000 00:00 0
7f5cbbdc6000-7f5cbbdc7000 ---p 00000000 00:00 0
7f5cbbdc7000-7f5cbbe68000 rw-p 00000000 00:00 0
7f5cbbe68000-7f5cbbe69000 ---p 00000000 00:00 0
7f5cbbe69000-7f5cbbf0a000 rw-p 00000000 00:00 0
7f5cbbf0a000-7f5cbbf0b000 ---p 00000000 00:00 0
7f5cbbf0b000-7f5cbbfac000 rw-p 00000000 00:00 0
7f5cbbfac000-7f5cbbfad000 ---p 00000000 00:00 0
7f5cbbfad000-7f5cbc04e000 rw-p 00000000 00:00 0
7f5cbc04e000-7f5cbc04f000 ---p 00000000 00:00 0
7f5cbc04f000-7f5cbc0f0000 rw-p 00000000 00:00 0
7f5cbc0f0000-7f5cbc0f1000 ---p 00000000 00:00 0
7f5cbc0f1000-7f5cbc192000 rw-p 00000000 00:00 0
7f5cbc192000-7f5cbc193000 ---p 00000000 00:00 0
7f5cbc193000-7f5cbc234000 rw-p 00000000 00:00 0
7f5cbc234000-7f5cbc235000 ---p 00000000 00:00 0
7f5cbc235000-7f5cbc2d6000 rw-p 00000000 00:00 0
7f5cbc2d6000-7f5cbc2d7000 ---p 00000000 00:00 0
7f5cbc2d7000-7f5cbc378000 rw-p 00000000 00:00 0
7f5cbc378000-7f5cbc379000 ---p 00000000 00:00 0
7f5cbc379000-7f5cbc41a000 rw-p 00000000 00:00 0
7f5cbc41a000-7f5cbc41b000 ---p 00000000 00:00 0
7f5cbc41b000-7f5cbc4bc000 rw-p 00000000 00:00 0
7f5cbc4bc000-7f5cbc4bd000 ---p 00000000 00:00 0
7f5cbc4bd000-7f5cbc55e000 rw-p 00000000 00:00 0
7f5cbc55e000-7f5cbc55f000 ---p 00000000 00:00 0
7f5cbc55f000-7f5cbc600000 rw-p 00000000 00:00 0
7f5cbc600000-7f5cbc601000 ---p 00000000 00:00 0
7f5cbc601000-7f5cbc6a2000 rw-p 00000000 00:00 0
7f5cbc6a2000-7f5cbc6a3000 ---p 00000000 00:00 0
7f5cbc6a3000-7f5cbc744000 rw-p 00000000 00:00 0
7f5cbc744000-7f5cbc745000 ---p 00000000 00:00 0
7f5cbc745000-7f5cbe951000 rw-p 00000000 00:00 0
7f5cbe951000-7f5cbe95c000 r--p 00000000 fd:03 40148578                   /usr/lib/libgmp.so.10.4.0
7f5cbe95c000-7f5cbe99f000 r-xp 0000b000 fd:03 40148578                   /usr/lib/libgmp.so.10.4.0
7f5cbe99f000-7f5cbe9b5000 r--p 0004e000 fd:03 40148578                   /usr/lib/libgmp.so.10.4.0
7f5cbe9b5000-7f5cbe9b7000 r--p 00063000 fd:03 40148578                   /usr/lib/libgmp.so.10.4.0
7f5cbe9b7000-7f5cbe9b8000 rw-p 00065000 fd:03 40148578                   /usr/lib/libgmp.so.10.4.0
7f5cbe9b8000-7f5cbe9bb000 r--p 00000000 fd:03 70454495                   /lib/libz.so.1.2.11
7f5cbe9bb000-7f5cbe9c9000 r-xp 00003000 fd:03 70454495                   /lib/libz.so.1.2.11
7f5cbe9c9000-7f5cbe9d0000 r--p 00011000 fd:03 70454495                   /lib/libz.so.1.2.11
7f5cbe9d0000-7f5cbe9d1000 r--p 00017000 fd:03 70454495                   /lib/libz.so.1.2.11
7f5cbe9d1000-7f5cbe9d2000 rw-p 00018000 fd:03 70454495                   /lib/libz.so.1.2.11
7f5cbe9d2000-7f5cbe9fe000 r--p 00000000 fd:03 17611231                   /usr/local/lib/libruby.so.2.7.1
7f5cbe9fe000-7f5cbec84000 r-xp 0002c000 fd:03 17611231                   /usr/local/lib/libruby.so.2.7.1
7f5cbec84000-7f5cbed7b000 r--p 002b2000 fd:03 17611231                   /usr/local/lib/libruby.so.2.7.1
7f5cbed7b000-7f5cbed84000 r--p 003a8000 fd:03 17611231                   /usr/local/lib/libruby.so.2.7.1
7f5cbed84000-7f5cbed85000 rw-p 003b1000 fd:03 17611231                   /usr/local/lib/libruby.so.2.7.1
7f5cbed85000-7f5cbed9d000 rw-p 00000000 00:00 0
7f5cbed9d000-7f5cbedb2000 r--p 00000000 fd:03 72679147                   /lib/ld-musl-x86_64.so.1
7f5cbedb2000-7f5cbedf9000 r-xp 00015000 fd:03 72679147                   /lib/ld-musl-x86_64.so.1
7f5cbedf9000-7f5cbee2d000 r--p 0005c000 fd:03 72679147                   /lib/ld-musl-x86_64.so.1
7f5cbee2e000-7f5cbee2f000 r--p 00090000 fd:03 72679147                   /lib/ld-musl-x86_64.so.1
7f5cbee2f000-7f5cbee30000 rw-p 00091000 fd:03 72679147                   /lib/ld-musl-x86_64.so.1
7f5cbee30000-7f5cbee33000 rw-p 00000000 00:00 0
7ffc11c0c000-7ffc1240b000 rw-p 00000000 00:00 0                          [stack]
7ffc12513000-7ffc12515000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]


Aborted (core dumped)

Push mode?

With this gem, I can poll the nats-streaming-server for new messages.

But I haven't been able to figure out how to create a client that receives messages using server-push.

Is this possible? Am I just missing something here?

Process closes when not manually held open, won't get published messages

Hi, I'm noticing an issue where a subscriber will not keep the process open by itself. This means that I need to manually keep the process open in order to await for incoming messages.

Example:

require "stan/client"

client = STAN::Client.new

opts = { servers: ["nats://127.0.0.1:4222"] }
client.connect("test-cluster", "my-client", nats: opts)

# send a bunch of messages
10.times do
  client.publish("channel", "hey")
end

# set up a subscriber
subscriber = client.subscribe("my-channel", start_at: :first) do | msg|
    puts "Got message #{msg.data}"
end

# Process ends without subscriber getting any messages 

The program ends without receiving any of the published messages. I'd expect the subscriber to keep open and await for messages, or at least have an option to do so?

user/password auth might be botched

I'm getting a supposedly internal error while trying to connect with user/password — the same setup without user/password actually works:

tester_1     |      Failure/Error: stan.connect USER_NATS_CLUSTER_ID, 'tester', nats: {servers: ["nats://#{user}:#{password}@#{USER_NATS_HOST}:#{USER_NATS_PORT}"]}
tester_1     |
tester_1     |      NoMethodError:
tester_1     |        undefined method `<<' for nil:NilClass
tester_1     |      # /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/io/client.rb:797:in `send_command'
tester_1     |      # /usr/local/bundle/gems/nats-pure-0.6.2/lib/nats/io/client.rb:370:in `subscribe'
tester_1     |      # /usr/local/bundle/gems/nats-streaming-0.2.2/lib/stan/client.rb:139:in `connect'
tester_1     |      # ./integ_spec.rb:66:in `block (3 levels) in <top (required)>'

I hope that someone can share a workaround, if any, at least.

Feature request: return ack.sequence on publish

This would be a great feature for CQRS implementations.

On (a)sync publish I'd love to know at which sequence position the published message was included in the subject/channel.

It seems the protocol would need to be expanded to include this feature.

Thoughts?

Thanks!

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.