High-performance PHP-to-Golang IPC bridge

Overview

High-performance PHP-to-Golang IPC bridge

Latest Stable Version GoDoc Linux macOS Windows Linters Go Report Card Codecov

PHPClasses Innovation Award

Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package. The library allows you to call Go service methods from PHP with a minimal footprint, structures and []byte support.
PHP source code can be found in this repository: goridge-php


See https://github.com/spiral/roadrunner - High-performance PHP application server, load-balancer and process manager written in Golang

Features

  • no external dependencies or services, drop-in (64bit PHP version required)
  • low message footprint (12 bytes over any binary payload), binary error detection
  • CRC32 header verification
  • sockets over TCP or Unix (ext-sockets is required), standard pipes
  • very fast (300k calls per second on Ryzen 1700X over 20 threads)
  • native net/rpc integration, ability to connect to existed application(s)
  • standalone protocol usage
  • structured data transfer using json
  • []byte transfer, including big payloads
  • service, message and transport level error handling
  • hackable
  • works on Windows
  • unix sockets powered (also on Windows)

Installation

GO111MODULE=on go get github.com/spiral/goridge/v3

Sample of usage

package main

import (
	"fmt"
	"net"
	"net/rpc"

	goridgeRpc "github.com/spiral/goridge/v3/pkg/rpc"
)

type App struct{}

func (s *App) Hi(name string, r *string) error {
	*r = fmt.Sprintf("Hello, %s!", name)
	return nil
}

func main() {
	ln, err := net.Listen("tcp", ":6001")
	if err != nil {
		panic(err)
	}

	_ = rpc.Register(new(App))

	for {
		conn, err := ln.Accept()
		if err != nil {
			continue
		}
		_ = conn
		go rpc.ServeCodec(goridgeRpc.NewCodec(conn))
	}
}

License

The MIT License (MIT). Please see LICENSE for more information.

Issues
  • Second call is too slow

    Second call is too slow

    Hi. I did: go get "github.com/spiral/goridge" composer require spiral/goridge cd ~/go/src/goridge/vendor/spiral/goridge/examples go run ./

    And ran the folowing script:

    `<?php use Spiral\Goridge; require "vendor/autoload.php";

    $t1 = microtime(true); $rpc = new Goridge\RPC( new Goridge\SocketRelay("127.0.0.1", 6001) ); echo $rpc->call("App.Hi", "Antony"); $t3 = (float)microtime(true) - (float)$t1;

    echo ": $t3 | "; $t1 = microtime(true); echo $rpc->call("App.Hi", "Antony"); $t2 = microtime(true); $t3 = (float)$t2 - (float)$t1; echo ": $t3" . PHP_EOL;`

    I got a result: Hello, Antony!: 0.00071406364440918 | Hello, Antony!: 0.041256904602051 Is it a bug? Or I made mistake?

    ** Thank for your job!

    B-performance 
    opened by swifft17 5
  • Allow Unix socket on Windows

    Allow Unix socket on Windows

    Windows 10 now supports basic functionality of AF_UNIX sockets. Consequently, restriction on Unix sockets on Windows was removed in Go and thus can be removed in goridge.

    B-missing feature A-network 
    opened by oakad 5
  • [BUG] RPC error message duplication

    [BUG] RPC error message duplication

    I tried this code:

    <?php
    
    use Spiral\Goridge\RPC\RPC;
    
    require __DIR__ . '/vendor/autoload.php';
    
    RPC::create('tcp://127.0.0.1:6001')
      ->call('unknown-method', null);
    

    I expected to see this happen:

    Error 'rpc: service/method request ill-formed: unknown-method' on tcp://127.0.0.1:6001
    

    Instead, this happened:

    Error 'rpc: service/method request ill-formed: unknown-method; rpc: service/method request ill-formed: unknown-method' on tcp://127.0.0.1:6001
    

    The version of RR used: 2.3.0 (stable)

    Errortrace, Backtrace or Panictrace

    *not required*
    
    A-network 
    opened by SerafimArts 4
  • PHP code removed

    PHP code removed

    PHP code now located in spiral/goridge-php repository. So, current state in master branch can be a little bit cleared.

    Yes, I know about #91. But this iteration must be made anyway, I think.

    A-other 
    opened by tarampampam 4
  • Getting ErrorException when the worker is stopped

    Getting ErrorException when the worker is stopped

    In production whenever the worker is being terminated by Roadrunner normally or by stopping the main process, I am getting an ErrorException with the following message:

    unpack(): Type C: not enough input, need 1, have 0
    

    on line: https://github.com/spiral/goridge/blob/c522eec9d8215c6059eeb4647d37003a2726e346/src/StreamRelay.php#L152

    Goridge version: v2.4.4 Roadrunner version: v1.5.1

    E-needstest E-medium B-bug 
    opened by sikhlana 4
  • STDIN is not readable

    STDIN is not readable

    Since version 2.2.0 (after execution composer update) i'v got an error:

    resource `in` must be readable in /app/vendor/spiral/goridge/php-src/StreamRelay.php:43
    

    In my code, I create StreamRelay using the following code:

    new \Spiral\Goridge\StreamRelay(\STDIN, \STDOUT);
    

    And got an error, describet above. It happens because since version 2.2.0 this package uses next assert:

        /**
         * Checks if stream is readable.
         *
         * @param resource $stream
         *
         * @return bool
         */
        private function assertReadable($stream): bool
        {
            $meta = stream_get_meta_data($stream);
            return in_array($meta['mode'], ['r', 'r+', 'w+', 'a+', 'x+', 'c+'], true);
        }
    

    Previos checking method was better: $this->assertMode($in, 'r')

    But this method does not allows to use binary safe mode (b), which appended to the STDIN and STDOUT by default:

    $ docker run --rm php:7.3.0-alpine php -r 'var_dump(stream_get_meta_data(\STDIN)["mode"]);'
    string(2) "rb"
    
    $ docker run --rm php:7.2.0-alpine php -r 'var_dump(stream_get_meta_data(\STDIN)["mode"]);'
    string(2) "rb"
    

    So, my applications cannot be started after update =(

    B-bug 
    opened by tarampampam 4
  • StreamRelay requires Sockets extension

    StreamRelay requires Sockets extension

    I tried to add metrics into my application and hit into following error:

    roadrunner_1  | WARN[0020] Error: Call to undefined function Spiral\Goridge\socket_create() in /www/vendor/spiral/goridge/php-src/SocketRelay.php:275 
    roadrunner_1  | WARN[0020] Stack trace:                                 
    roadrunner_1  | WARN[0020] #0 /www/vendor/spiral/goridge/php-src/SocketRelay.php(185): Spiral\Goridge\SocketRelay->createSocket() 
    roadrunner_1  | WARN[0020] #1 /www/vendor/spiral/goridge/php-src/SocketRelay.php(88): Spiral\Goridge\SocketRelay->connect() 
    roadrunner_1  | WARN[0020] #2 /www/vendor/spiral/goridge/php-src/RPC.php(47): Spiral\Goridge\SocketRelay->send('metrics.Add\x00\x00\x00\x00...', 20) 
    roadrunner_1  | WARN[0020] #3 /www/vendor/spiral/roadrunner/src/Metrics.php(44): Spiral\Goridge\RPC->call('metrics.Add', Array) 
    roadrunner_1  | WARN[0020] #4 /www/psr-worker.php(29): Spiral\RoadRunner\Metrics->add('app_metric_coun...', 1) 
    roadrunner_1  | WARN[0020] #5 {main}                                    
    

    RR version is 1.4.7. The reason is inexisting Sockets extension.

    Suggestion: to require it in composer.json as "ext/sockets" OR to mention it in documentation and to throw exception if (!extension_loaded('sockets')) in createSocket

    P.S. There are also some json_encode in Spiral\Goridge\RPC, so it's better to add ext/json to require too.

    A-docs 
    opened by batyrmastyr 4
  • Make slice error

    Make slice error

    got a weird error for a service that was already running for a week: when looking at the code it can only be triggered if leftBytes is negative? is that possible?

    data = make([]byte, 0, leftBytes)

    panic: runtime error: makeslice: cap out of range
    goroutine 89191655 [running]:
    github.com/spiral/goridge.(*SocketRelay).Receive(0xc420142330, 0x0, 0x0, 0x0, 0x28, 0xc42047bda0, 0x0, 0x0)
            /Users/jayme/Documents/projects/go/src/github.com/spiral/goridge/socket.go:54 +0x20e
    github.com/spiral/goridge.(*Codec).ReadRequestBody(0xc420346000, 0x0, 0x0, 0x0, 0x0)
            /Users/jayme/Documents/projects/go/src/github.com/spiral/goridge/codec.go:48 +0x48
    net/rpc.(*Server).readRequest(0xc4201360a0, 0x93b520, 0xc420346000, 0x725fc0, 0x992af8, 0x93b520, 0xc420346000, 0x79a91f, 0x28, 0x0, ...)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:547 +0xe1
    net/rpc.(*Server).ServeCodec(0xc4201360a0, 0x93b520, 0xc420346000)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:460 +0x77
    net/rpc.ServeCodec(0x93b520, 0xc420346000)
            /usr/local/Cellar/go/1.9/libexec/src/net/rpc/server.go:669 +0x41
    created by main.main
    
    B-bug 
    opened by jrots 4
Releases(v3.5.1)
Owner
Spiral Scout
Spiral Scout is a full-service digital agency, providing design, development and online marketing services to businesses around San Francisco and beyond.
Spiral Scout
PHP bindings for the Go programming language (Golang)

PHP bindings for Go This package implements support for executing PHP scripts, exporting Go variables for use in PHP contexts, attaching Go method rec

Alex Palaistras 868 Aug 10, 2022
PHP parser written in Go

PHP Parser written in Go This project uses goyacc and ragel tools to create PHP parser. It parses source code into AST. It can be used to write static

Vadym Slizov 886 Aug 9, 2022
Transpiling fortran code to golang code

f4go Example of use > # Install golang > # Compile f4go > go get -u github.com/Konstantin8105/f4go > cd $GOPATH/src/github.com/Konstantin8105/f4go > g

Konstantin 32 Jul 11, 2022
Golang->Haxe->CPP/CSharp/Java/JavaScript transpiler

TARDIS Go -> Haxe transpiler Haxe -> C++ / C# / Java / JavaScript Project status: a non-working curiosity, development currently on-ice The advent of

TARDIS Go 418 Jul 13, 2022
A JavaScript interpreter in Go (golang)

otto -- import "github.com/robertkrimen/otto" Package otto is a JavaScript parser and interpreter written natively in Go. http://godoc.org/github.com/

Robert Krimen 6.8k Aug 9, 2022
A BASIC interpreter written in golang.

05 PRINT "Index" 10 PRINT "GOBASIC!" 20 PRINT "Limitations" Arrays Line Numbers IF Statement DATA / READ Statements Builtin Functions Types 30 PRINT "

Steve Kemp 281 Aug 8, 2022
Expression evaluation in golang

Gval Gval (Go eVALuate) provides support for evaluating arbitrary expressions, in particular Go-like expressions. Evaluate Gval can evaluate expressio

null 522 Aug 12, 2022
golang AST matcher

goastch (GO AST matCH) Introduction Inspired by ast matcher. There are four different basic categories of matchers: Node Matchers: Matchers that match

Helloyi He 14 Apr 19, 2022
Scriptable interpreter written in golang

Anko Anko is a scriptable interpreter written in Go. (Picture licensed under CC BY-SA 3.0, photo by Ocdp) Usage Example - Embedded package main impor

mattn 1.3k Aug 1, 2022
Arbitrary expression evaluation for golang

govaluate Provides support for evaluating arbitrary C-like artithmetic/string expressions. Why can't you just write these expressions in code? Sometim

George Lester 2.6k Aug 12, 2022
hotbuild - a cross platform hot compilation tool for golang

hotbuild A cross platform hot compilation tool By monitoring the modification of the project directory file, the recompilation and running are automat

wander 189 Aug 7, 2022
The golang tool of the zig compiler automatically compiles different targets according to the GOOS GOARCH environment variable. You need to install zig.

The golang tool of the zig compiler automatically compiles different targets according to the GOOS GOARCH environment variable. You need to install zig.

dosgo 27 Jul 17, 2022
Tgo - Test Helpers for Standard Golang Packages

Test Helpers for Standard Golang Packages see example_test.go go test --- FAIL:

krhubert 1 Apr 26, 2022
Logexp - Logical expression compiler for golang

Logical Expression Compiler Functions: - Compile(exp string) - Match(text string

Jinglever 1 Jan 24, 2022
Runcmd - just golang binary that runs commands from url or local file and logs output

runcmd just golang binary that runs commands from url or local file and logs out

boredhackerblog 0 Feb 2, 2022
A compiler for the ReCT programming language written in Golang

ReCT-Go-Compiler A compiler for the ReCT programming language written in Golang

null 6 Apr 7, 2022
🧙 High-performance PHP-to-Golang IPC/RPC bridge

High-performance PHP-to-Golang IPC bridge Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/r

RoadRunner 1.1k Aug 5, 2022
Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package.

Goridge is high performance PHP-to-Golang codec library which works over native PHP sockets and Golang net/rpc package. The library allows you to call Go service methods from PHP with a minimal footprint, structures and []byte support.

Spiral Scout 1.1k Aug 5, 2022
Bridge Chrome "native messages" to Discord's IPC socket

chrome-discord-bridge This code bridges Chrome "native messages" to Discord's IPC socket. It's written in Go with no third-party dependencies. It's in

Dean Scarff 1 Jul 31, 2022
PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. You can use PHP like functions in your app, module etc. when you add this module to your project.

PHP Functions for Golang - phpfuncs PHP functions implementation to Golang. This package is for the Go beginners who have developed PHP code before. Y

Serkan Algur 51 Aug 5, 2022
Apex-api-bridge - Bridge between apexlegendsapi and ApeStats

apex-api-sync This app updates a mongo instance with the players most recent dat

null 1 Feb 17, 2022
High-performance PHP application server, load-balancer and process manager written in Golang

[RR2-BETA] RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports runnin

Spiral Scout 6.7k Aug 15, 2022
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 6.7k Aug 12, 2022
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 6.7k Aug 13, 2022
High-performance PHP application server, load-balancer and process manager written in Golang

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 6.1k Dec 9, 2021
🔑A high performance Key/Value store written in Go with a predictable read/write performance and high throughput. Uses a Bitcask on-disk layout (LSM+WAL) similar to Riak.

bitcask A high performance Key/Value store written in Go with a predictable read/write performance and high throughput. Uses a Bitcask on-disk layout

James Mills 7 Apr 15, 2022
RoadRunner: an open-source high-performance PHP application server, load balancer, and process manager

RoadRunner is an open-source (MIT licensed) high-performance PHP application server, load balancer, and process manager. It supports running as a serv

Spiral Scout 0 Jan 13, 2022
the pluto is a gateway new time, high performance, high stable, high availability, easy to use

pluto the pluto is a gateway new time, high performance, high stable, high availability, easy to use Acknowledgments thanks nbio for providing low lev

mobus 2 Sep 19, 2021