Giter Club home page Giter Club logo

lightning's Introduction

Edge
Serverside non-blocking IO in Swift
Ask questions in our Slack channel!

Lightning

(formerly Edge)

Swift Build Status codecov Slack Status

Node

Lightning is an HTTP Server and TCP Client/Server framework written in Swift and inspired by Node.js. It runs on both OS X and Linux. Like Node.js, Lightning uses an event-driven, non-blocking I/O model. In the same way that Node.js uses libuv to implement this model, Lightning uses libdispatch.

This makes Lightning fast, efficient, and most crutially single-threaded by default. You simply do not need to worry about locks/mutexes/semaphores/etc if you have server-side state. Of course, Lightning applications can make use of libdispatch to easily offload heavy processing to a background thread if necessary.

Reactive Programming

Lightning's event API embraces Functional Reactive Programming by generalizing the familiar concept of promises. This API is called StreamKit.

StreamKit's architecture is inspired by both ReactiveCocoa and RxSwift.

Why did we reimplement?
  • Lightning should be easy to use out of the box.
  • Lightning is optimized for maximum performance, which requires careful tuning of the internals.
  • The modified API is meant to be more similar to the familiar concepts of Futures and Promises.
  • We don't want to be opinionated about any one framework. We want it to be easy to integate Lightning with either ReactiveCocoa or RxSwift.

FRP, greatly simplies management of asynchronous events. The general concept is that we can build a spout which pushes out asynchronous events as they happen. Then we hookup a pipeline of transformations that operate on events and pass the transformed values along. We can even do things like merge streams in interesting ways! Take a look at some of these operations or watch this talk about how FRP is used at Netflix.

Installation

Lightning is available as a Swift 3/4 package. Simply add Lightning as a dependency to your Swift Package.

Swift 3

import PackageDescription

let package = Package(
    name: "MyProject",
    dependencies: [
        .Package(url: "https://github.com/skylab-inc/Lightning.git", majorVersion: 0, minor: 3)
    ]
)

Swift 4

// swift-tools-version:4.0
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

let package = Package(
    name: "MyProject",
    dependencies: [
        .package(url: "https://github.com/skylab-inc/Lightning.git", from: "0.3.0"),
    ]
)

Usage

Routing

import Lightning
import Foundation

// Create an API router.
let api = Router()

// Add a GET "/users" endpoint.
api.get("/users") { request in
    return Response(status: .ok)
}

// NOTE: Equivalent to `api.post("/auth/login")`
let auth = api.subrouter("/auth")
auth.post("/login") { request in
    return Response(status: .ok)
}

// Middleware to log all requests
// NOTE: Middleware is a simple as a map function or closure!
let app = Router()
app.map { request in
    print(request)
    return request
}

// Mount the API router under "/v1.0".
app.add("/v1.0", api)

// NOTE: Warnings on all unhandled requests. No more hanging clients!
app.any { _ in
    return Response(status: .notFound)
}

// Start the application.
app.start(host: "0.0.0.0", port: 3000)

Raw HTTP

import Lightning
import Foundation

func handleRequest(request: Request) -> Response {
    print(String(bytes: request.body, encoding: .utf8)!)
    return try! Response(json: ["message": "Message received!"])
}

let server = HTTP.Server()
server.listen(host: "0.0.0.0", port: 3000).startWithNext { client in

    let requestStream = client.read()
    requestStream.map(handleRequest).onNext{ response in
        client.write(response).start()
    }

    requestStream.onFailed { clientError in
        print("Oh no, there was an error! \(clientError)")
    }

    requestStream.onCompleted {
        print("Goodbye \(client)!")
    }

    requestStream.start()
}

RunLoop.runAll()

TCP

import Lightning
import Foundation

let server = try! TCP.Server()
try! server.bind(host: "0.0.0.0", port: 50000)
    
server.listen().startWithNext { connection in
    let byteStream = connection.read()
    let strings = byteStream.map { String(bytes: $0, encoding: .utf8)! }
    
    strings.onNext { message in
        print("Client \(connection) says \"\(message)\"!")
    }
    
    strings.onFailed { error in
        print("Oh no, there was an error! \(error)")
    }
    
    strings.onCompleted {
        print("Goodbye \(connection)!")
    }
    
    strings.start()
}

RunLoop.runAll()

Lightning is not Node.js

Lightning is not meant to fulfill all of the roles of Node.js. Node.js is a JavaScript runtime, while Lightning is a TCP/Web server framework. The Swift compiler and package manager, combined with third-party Swift packages, make it unnecessary to build that functionality into Lightning.

lightning's People

Contributors

cloutiertyler avatar king7532 avatar kmcgill7 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  avatar  avatar  avatar  avatar  avatar  avatar

lightning's Issues

Unable to join the Slack team

When I click on the Slack link it asks me to sign in and I cannot use an existing Slack team credentials. Can you add me to the Swiftedge slack or make it a public group? Thanks.

I love the idea of this framework and can't wait to experiment with it. Thanks.

Asynchrony in the router

The router methods should be able to take closure parameters which return SignalTypes, plain ol' closures, and probably also Promises.

I'd like to add Promises to Reflex or at least see how they relate to Signals better.

Example Application

I know that Edge is very new but it would be great to put together some kind of basic demo application. After I spend a bit more time with the codebase I would be happy to do this :)

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.