Skip to content

(New Feature) Add EventEmitter to AssemblyScript? #1782

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
JairusSW opened this issue Apr 1, 2021 · 5 comments
Closed

(New Feature) Add EventEmitter to AssemblyScript? #1782

JairusSW opened this issue Apr 1, 2021 · 5 comments

Comments

@JairusSW
Copy link
Contributor

JairusSW commented Apr 1, 2021

Hello everyone,
I was wondering if AssemblyScript planned to support an EventEmitter. I believe it would be a good addition because we could add stream support on top of it. I already have a working example that seems to work seamlessly. Adding an EventEmitter would stray from the Standard Library, but I believe it would be worth it. 😉

Working Example

// EventEmitter Class
export class EventEmitter {
    private maxListeners: number = 10
    private pointers: Map<string, Array<i32>> = new Map<string, Array<i32>>()
    constructor() {}
    emit(event: string, data: string): void {
      if (this.pointers.has(event)) {
        const ptrs = this.pointers.get(event)
        for (let i = 0; i < ptrs.length; i++) {
          call_indirect(ptrs[i], data)
        }
      }
    }
    on(event: string, callback: (data: string) => void): void {
      if (!this.pointers.has(event)) {
        this.pointers.set(event, [load<i32>(changetype<usize>(callback))])
      } else {
        const ptrs = this.pointers.get(event)
        if (ptrs.length > this.maxListeners) {
          throw new Error(`MaxListenersExceededWarning: Possible EventEmitter memory leak detected. ${ptrs.length} ${event} listeners added to [EventEmitter]. Use emitter.setMaxListeners() to increase limit`)
        }
        ptrs.push(load<i32>(changetype<usize>(callback)))
        this.pointers.set(event, ptrs)
      }
    }
    getMaxListeners(): number {
      return this.maxListeners
    }
    setMaxListeners(n: number): void {
      this.maxListeners = n
    }
}
@JairusSW JairusSW changed the title Add EventEmitter to AssemblyScript? (New Feature) Add EventEmitter to AssemblyScript? Apr 1, 2021
@dcodeIO
Copy link
Member

dcodeIO commented Apr 2, 2021

The event emitter pattern typically used around Node.js is a little odd, as it requires quite a bit of dynamicness that is neither type safe nor particularly efficient. I know that @jtenner thought about this quite a lot in context of the (now stale) node lib, and my impression from it was that we'll very likely need either some sort of compiler integration (even though I don't know how that would work yet) or we'll have to resort to a safer (and sadly Node.js-incompatible) pattern.

@JairusSW
Copy link
Contributor Author

JairusSW commented Apr 2, 2021

@dcode, Okay! I believe I'll make it into a GitHub module so I can implement

fs.createReadStream(file: string): ReadableStream

in WAKE. :)
I agree, its probably not the best for AS rn.

@JairusSW
Copy link
Contributor Author

JairusSW commented Apr 2, 2021

Closing...

@JairusSW JairusSW closed this as completed Apr 2, 2021
@JairusSW JairusSW reopened this Apr 5, 2021
@JairusSW
Copy link
Contributor Author

JairusSW commented Apr 5, 2021

@dcodeIO , As of dynamicness, It only handles strings at the moment, and for performance, it seems to be ~1.5-2x faster than js when operating <500k times> If it is over 500k - 1m ops, NodeJS is much faster.... Here's a benchmark I performed.

EventEmitter Bench.
NodeJS vs. AssemblyScript

AssemblyScript: v0.18.19
NodeJS: v14.16.0

Bench #1 (1k ops)

  • NodeJS: 0.237ms
  • AssemblyScript: 0.142ms

Bench #2 (10k ops)

  • NodeJS: 2.457ms
  • AssemblyScript: 1.477ms

Bench #3 (100k ops)

  • NodeJS: 5.362ms
  • AssemblyScript: 3.975ms

Bench #4 (250k ops)

  • NodeJS: 8.036ms
  • AssemblyScript: 8.266ms

Bench #5 (500k ops)

  • NodeJS: 11.589ms
  • AssemblyScript: 18.931ms

@JairusSW
Copy link
Contributor Author

Closing (inactive)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants