add close method for cleaning up instead of waiting for GC