Giter Club home page Giter Club logo

kilim-fiber's Introduction

This is a fiber implementation for java.
It originates from the kilim project,
modified & simplified by @taowen,
and I, pushed it into production use after fixing some annoying bugs.

What a pity for we javaers could not using fiber/coroutines happily in our programming life.
Even the most recent java release —— java8, has no fiber/coroutine support.
And, we can't see any clue of this feature in the upcoming java9 plan, it's painful!

Then this little lib —— kilim-fiber, would be a cure for this, at least in the near future.

It's simple, fast and easy to use.

It works smoothly in our high throughput online systems, which deals 0.2 billion requests per-day, under jdk1.6/1.7. So the correctness is now proven.

For more documents and discussion, please refer to the wiki.

—— notes by pf_miles


This is a modified version Only fiber related stuff remains, mailbox and scheduler has been removed. There is no implicit multithreading, messaging or scheduling in this version.


Kilim v1.0 Copyright (c) 2006 Sriram Srinivasan. (kilim at malhar.net)


This software is released under an MIT-style licesne (please see the License file).

Please see docs/manual.txt and docs/kilim_ecoop08.pdf for a brief introduction.

Please send comments, queries, code fixes, constructive criticisms to kilim at malhar.net

kilim-fiber's People

Contributors

kilim avatar krestenkrab avatar pellcorp avatar pfmiles avatar sriram-srinivasan avatar taowen avatar zbigniew-mandziejewicz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

moviewang xwh4022

kilim-fiber's Issues

class rewrite的动作不应该发生在编译期,发生在第一次运行时更合理

若遇到multi-module的maven项目,被依赖的jar包若先于依赖它的jar包被编译、改写,那么等到依赖它的jar包编译时,就会报编译错误;

应该坚持的使用原则是,类改写仅仅发生在运行时或组装产品包之前,如组装war包前,而不应该将install到maven仓库中的jar包改写,这样会导致很多问题;

那么可能的选项就只有instrumentation或maven war工程在组装war时改写了

info

hi how it possible to implement fiber in java?

内联asm

asm被无数项目依赖,容易发生冲突,kilim这样的基础类库应“内联”asm

在weave interface时,将原本的pausable方法weave成了非abstract函数

例如这样一个存在于interface中的函数签名:

public abstract java.lang.Object asyncInvokeMethod(com.test.ocean.meta.domain.service.ServiceMeta<T>, java.lang.Object[], long, com.test.ocean.context.InvokerContext, com.test.openapi.lang.BizStackTrace) throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable;
    flags: ACC_PUBLIC, ACC_ABSTRACT
    Exceptions:
      throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable

被weave成了:

public abstract java.lang.Object asyncInvokeMethod(com.test.ocean.meta.domain.service.ServiceMeta<T>, java.lang.Object[], long, com.test.ocean.context.InvokerContext, com.test.openapi.lang.BizStackTrace, kilim.Fiber) throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable;
    flags: ACC_PUBLIC, ACC_ABSTRACT
    Exceptions:
      throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable
    Signature: #34                          // (Lcom/test/ocean/meta/domain/service/ServiceMeta<TT;>;[Ljava/lang/Object;JLcom/test/ocean/context/InvokerContext;Lcom/test/openapi/lang/BizStackTrace;Lkilim/Fiber;)Ljava/lang/Object;

  public java.lang.Object asyncInvokeMethod(com.test.ocean.meta.domain.service.ServiceMeta<T>, java.lang.Object[], long, com.test.ocean.context.InvokerContext, com.test.openapi.lang.BizStackTrace) throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable;
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=7, args_size=6
         0: invokestatic  #26                 // Method kilim/Task.errNotWoven:()V
         3: aconst_null   
         4: areturn       
    Exceptions:
      throws com.test.openapi.exception.invoke.InvokeMethodException, com.test.openapi.exception.invoke.InvokeMethodTargetException, com.test.openapi.exception.invoke.InvokeMethodTimeoutException, kilim.Pausable

这种方式在java8中是合法的,因为java8的interface函数能拥有函数体,但java8之前的版本不行

在动态代理类路径较深时,有时出现产品代码抛出异常无法被捕获的情况

这是因为Fiber类内部默认采用stateStack数组跟踪协程路径,但其默认长度为10;
且Fiber的up和down函数是无法在其它代理库如cglib产生的代码中被调用的,因此,当代理类层次过深,比如超过10时,就会有一些callstack未被stateStack数组记录,这样stateStack的长度就会比实际callstack小;这时候如果调用upEx时,fiber代码可能会抛出ArrayIndexOutOfBoundsException, 导致实际的产品catch代码无法被执行;

解决办法:只需在upEx代码中加入ensureSize逻辑即可

将单函数类判断成了SAM

public class App {

public static void main(String[] args) {
    final Task task = new Task() {

        @Override
        public void execute() throws Pausable {
            System.out.println("hello");
            Foo f = new Foo();
            f.hehe();
            System.out.println("world");
        }

    };
    task.run();
    System.out.println("hey there");
    task.run();
    System.out.println("at last...");
}

public static class Foo {

    public void hehe() throws Pausable {
        System.out.println("foo hehe");
        new Bar().haha();
        System.out.println("Foo hehe end");
    }

    public void test() {
    }
}

public static class Bar {

    public void haha() throws Pausable {
        System.out.println("haha");
        Task.yield();
        System.out.println("hoho");
    }

    public void test() {
    }

}
}

上述代码,若Foo或Bar中任意一个的test方法被删除,则会报错:

Exception in thread "main" java.lang.RuntimeException: task is done with exception
at kilim.Task._runExecute(Task.java:318)
at kilim.Task.run(Task.java:328)
at test.App.main(App.java:23)
Caused by: java.lang.IncompatibleClassChangeError: Found class test.App$Bar, but interface was     expected
at test.App$Foo.$shim$1(App.java)
at test.App$Foo.hehe(App.java:33)
at test.App$1.execute(App.java:18)
at kilim.Task._runExecute(Task.java:303)
... 2 more

原因是kilim的ClassWeaver将只有一个方法的类错判成了jdk8的functional interface,从而为其生成了SAM(single abstract method) methods

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.