refactor to support both half-open and closed