Tornex
View SourceAn Elixir library providing robust API call planning and execution for the Torn City API.
NOTE
Currently, tornex is intended to work on single-node deployments. Multi-node deployments will experience issues with ratelimiting.
Features
- Efficient API ratelimiting and planning using buckets and prioritized requests
:telemetry
-based logging (with included support for PromEx)- Support for APIv1 and APIv2
Roadmap
- [ ] Per-IP/node global ratelimit
- [ ] Combine similar queries to reduce throughput
- [ ] Multi-node support
- [ ] APIv2 struct coalescing using torngen
- [ ] APIv2 mocking server using torngen
Installation
Once available in Hex, the library can be installed
by adding tornex
to your list of dependencies in mix.exs
:
def deps do
[
{:tornex, "~> 0.1.0"}
]
end
For latest changes, you can also install the library directly from GitHub:
def deps do
[
{:tornex, github: "Tornium/tornex"}
]
end
Usage
Add the supervisor Tornex.Scheduler.supervisor
to your application supervisor. If you are using the default telemetry handler using Tornex.Telemetry.attach_default_handler
, make sure to start the handler before starting the supervisor.
Create a Tornex.Query
struct containing the request information:
request = %Tornex.Query{
resource: "v2/user",
resource_id: 1,
key: api_key,
selections: ["criminalrecord", "basic"],
key_owner: 2383326,
nice: 10
}
The query struct must contain the following values:
resource
: The name of the resource in v1 or v2. Prepend withv2/
if you're using APIv2.resource_id
: The ID of the resource even if the request is against the key owner's user, faction, etc.key
: The API key to be used.key_owner
: Any other unique identifier (suggested to use Torn ID) of the API key owner.nice
: The priority of the request (following the Linux niceness values) where -20 is the highest priority and 19 is the lowest priority.
The request can be enqueued into the key owner's queue with Tornex.Scheduler.Bucket.enqueue/1
to be made depending on the request's priority and the state of the key owner's queue. Or the request can be performed immediately with Tornex.API.torn_get/1
which performs no ratelimiting. Both methods are blocking though.
response = Tornex.Scheduler.Bucket.enqueue(request)
case response do
{:error, :timeout} ->
IO.puts("timeout")
{:error, _} ->
IO.puts("unknown")
%{"name" => name, "criminalrecord" => %{"total" => crime_count}} ->
IO.puts("#{name} => #{crime_count} crimes")
end
Documentation
Documentation can be generated with ExDoc and published on HexDocs. Once published, the docs can be found at https://hexdocs.pm/tornex.
License
Copyright 2024-2025 tiksan
This project is licensed under Apache 2.0; see LICENSE.md for more details.