Crystal: Does Crystal utilize multiple cores / is it a right language for me?

Created on 12 Jun 2016  路  4Comments  路  Source: crystal-lang/crystal

Hey everyone!

The entire reason why I am moving to Crystal is because on node, we have to utilize "multiple instances", and then utilize Redis to share memory (and also for the Pub Sub System). Which is fine! I had no problem doing that, and it's a fairly easy way to scale.

However, let's say 1000 Websocket connections are active on an Xeon E3 (Using Kemal). 500 Players are in 83 games (6 players each). Each player is moving around the map and sending socket data to the other 5 players in their respective game. [This is not including Player Skills, Dropping an Item, Chatting, Monster Loot drops, etc, etc].

With nodejs, I would have to split these players up on multiple nodes and then either use Redis` Pub Sub to notify each time a player moves [since they will be on different node instances] -- (which is way too much overhead). OR through a Unix Socket (IPC)... or just simply transfer that user to that instance before joining the game.

The reason I ask is because I made a similar topic in the Reddit golang sub weeks ago. And they said using "goroutines and channels" would be necessary. Then, I got a message from someone saying "Crystal would do all that stuff for you".

The problem is though, I really love Crystal's syntax and want to switch. I am just not sure how many connections "1 instance" can handle on a Crystal TCP/Websocket Server.

Do we need to spin up multiple crystal instances, or just 1, and communicate through IPC? This is assuming Crystal handles utilizing multiple cores in the background if we do use IPC. If that makes sense, I'm kind of lost, but thanks!

question

Most helpful comment

@Dillybob92 Elixir might be better suited for your use-case. While it isn't as fast Crystal in terms of raw compute, it does run on multiple cores, and even multiple hosts (connected together directly, without needing an intermediate service such as Redis). Elixir runs on the Erlang VM which can handle millions of connections per server. It's also easier to write concurrent code (that actually runs in parallel) using a functional language, with immutable data, and no shared state. Instead of Channels/[Fibers/Goroutines] as seen in Crystal/Go, you have isolated "processes" (an even lighter version of Goroutines/Fibers), which can not only be distributed across multiple cpu cores, but multiple hosts.

I personally prefer Crystal/Go/Rust for command-line applications (fantastic for client-side/cross-platform distribution) or compute-intensive server applications. For any other networking-related needs, it's hard to beat Elixir (Erlang) in my opinion.

All 4 comments

Crystal is currently a mixture of Go and Node in that regard. The concurrency model is largely that of Go, fibers (goroutines) and channels. There's a runtime scheduler based on libevent that resumes fibers as the IO they blocked on becomes available, while a fiber is blocked another one is run. However that currently happens in a single thread.

That said the current plan is to use a thread pool and automatically distribute fibers among in, just like Go. We're just not there _yet_.

As to whether Crystal could handle your load on a single core, I don't know and there's no general answer to it, it largely depends on how computationally expensive your game logic is. Being a compiled language I expect it to certainly have a higher throughput than Node.

Please note that we have a mailing list, a subreddit, a IRC channel and our community is active on StackOverflow too, I'm closing this as it's not an issue with the language that needs to be tracked in its issue tracker.

Did you just copy-and-paste this? Almost the same exact thing was posted to the Nim bug tracker...

Yeah I did! That's me. I'm trying to find a new language to move to from nodejs.

@Dillybob92 Elixir might be better suited for your use-case. While it isn't as fast Crystal in terms of raw compute, it does run on multiple cores, and even multiple hosts (connected together directly, without needing an intermediate service such as Redis). Elixir runs on the Erlang VM which can handle millions of connections per server. It's also easier to write concurrent code (that actually runs in parallel) using a functional language, with immutable data, and no shared state. Instead of Channels/[Fibers/Goroutines] as seen in Crystal/Go, you have isolated "processes" (an even lighter version of Goroutines/Fibers), which can not only be distributed across multiple cpu cores, but multiple hosts.

I personally prefer Crystal/Go/Rust for command-line applications (fantastic for client-side/cross-platform distribution) or compute-intensive server applications. For any other networking-related needs, it's hard to beat Elixir (Erlang) in my opinion.

Was this page helpful?
0 / 5 - 0 ratings