def writer_thread(stream, queue):
    try:
        while True:
            to_write = queue.get()
            to_json = getattr(to_write, 'to_json', None)
            if to_json is not None:
                # Some protocol message
                to_write.seq = _next_seq()
                try:
                    to_write = to_json()
                except:
                    debug_exception('Error serializing %s to json.' %
                                    (to_write, ))
                    continue

            if DEBUG:
                debug('Writing: %s\n' % (to_write, ))

            if to_write.__class__ == bytes:
                as_bytes = to_write
            else:
                as_bytes = to_write.encode('utf-8')

            stream.write('Content-Length: %s\r\n\r\n' % (len(as_bytes)))
            stream.write(as_bytes)
            stream.flush()
    except:
        debug_exception()
예제 #2
0
def _notify_on_exited(process, on_exited):
    try:
        process.wait()
        if DEBUG:
            debug('notify process exited\n')
        on_exited()
    except:
        debug_exception()
예제 #3
0
def _read_stream(stream, on_line, category):
    try:
        while True:
            output = stream.readline()
            if len(output) == 0:
                break
            on_line(output, category)
    except:
        debug_exception()
def reader_thread(stream, process_command):
    try:
        while True:
            data = read(stream)
            if data is None:
                break
            protocol_message = base_schema.from_dict(data)
            process_command(protocol_message)
    except:
        debug_exception()
def main():
    '''
    Starts the debug adapter (creates a thread to read from stdin and another to write to stdout as 
    expected by the vscode debug protocol).
    
    We pass the command processor to the reader thread as the idea is that the reader thread will
    read a message, convert it to an instance of the message in the schema and then forward it to
    the command processor which will interpret and act on it, posting the results to the writer queue.
    '''
    try:
        import sys
        try:
            from queue import Queue
        except ImportError:
            from Queue import Queue

        write_queue = Queue()
        command_processor = CommandProcessor(write_queue)

        if DEBUG:
            debug('Starting. Args: %s\n' % (', '.join(sys.argv), ))

        write_to = sys.stdout
        read_from = sys.stdin

        if sys.version_info[0] <= 2:
            if sys.platform == "win32":
                # must read streams as binary on windows
                import os, msvcrt
                msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY)
                msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
        else:
            # Py3
            write_to = sys.stdout.buffer
            read_from = sys.stdin.buffer

        writer = threading.Thread(target=writer_thread,
                                  args=(write_to, write_queue))
        reader = threading.Thread(target=reader_thread,
                                  args=(read_from, command_processor))

        reader.start()
        writer.start()

        reader.join()
        writer.join()
    except:
        debug_exception()

    debug('exiting main.\n')
예제 #6
0
 def send_to_stdin(self, expression):
     popen = self._popen
     if popen is not None:
         import threading
         try:
             debug('Sending: %s to stdin.' % (expression,))
             def write_to_stdin(popen, expression):
                 popen.stdin.write(expression)
                 if not expression.endswith('\r') and not expression.endswith('\n'):
                     popen.stdin.write('\n')
                 popen.stdin.flush()
                 
             # Do it in a thread (in theory the OS could have that filled up and we would never complete
             # trying to write -- although probably a bit far fetched, let's code as if that could actually happen).
             t = threading.Thread(target=write_to_stdin, args=(popen, expression))
             t.setDaemon(True)
             t.start()
         except:
             debug_exception('Error writing: >>%s<< to stdin.' % (expression,))
    def __call__(self, protocol_message):
        if DEBUG:
            debug('Process json: %s\n' %
                  (json.dumps(protocol_message.to_dict(),
                              indent=4,
                              encoding='utf-8',
                              sort_keys=True), ))

        try:
            if protocol_message.type == 'request':
                method_name = 'on_%s_request' % (protocol_message.command, )
                on_request = getattr(self, method_name, None)
                if on_request is not None:
                    on_request(protocol_message)
                else:
                    if DEBUG:
                        debug(
                            'Unhandled: %s not available in CommandProcessor.\n'
                            % (method_name, ))
        except:
            debug_exception()
예제 #8
0
def from_dict(dct):
    msg_type = dct.get('type')
    if msg_type is None:
        raise ValueError('Unable to make sense of message: %s' % (dct, ))

    if msg_type == 'request':
        cls = _requests_to_types[dct['command']]
        try:
            return cls(**dct)
        except:
            msg = 'Error creating %s from %s' % (cls, dct)
            debug_exception(msg)
            raise ValueError(msg)

    elif msg_type == 'response':
        cls = _responses_to_types[dct['command']]
        try:
            return cls(**dct)
        except:
            msg = 'Error creating %s from %s' % (cls, dct)
            debug_exception(msg)
            raise ValueError(msg)

    raise ValueError('Unable to create message from dict: %s' % (dct, ))