code: async function getSession(ctx) {
      if (!matchPath(ctx)) return
      if (storeStatus === 'pending') {
        debug('store is disconnect and pending')
        await waitStore
      } else if (storeStatus === 'unavailable') {
        debug('store is unavailable')
        throw new Error('session store is unavailable')
      }
  
      if (!ctx.sessionId) {
        ctx.sessionId = sessionIdStore.get.call(ctx)
      }
  
      let session
      let isNew = false
      if (!ctx.sessionId) {
        debug('session id not exist, generate a new one')
        session = generateSession()
        ctx.sessionId = genSid.call(ctx, 24)
        isNew = true
      } else {
        try {
          session = await store.get(ctx.sessionId)
          debug('get session %j with key %s', session, ctx.sessionId)
        } catch (err) {
          if (err.code === 'ENOENT') {
            debug('get session error, code = ENOENT')
          } else {
            debug('get session error: ', err.message)
            errorHandler(err, 'get', ctx)
          }
        }
      }
  
      // make sure the session is still valid
      if (!session ||
        !valid(ctx, session)) {
        debug('session is empty or invalid')
        session = generateSession()
        ctx.sessionId = genSid.call(ctx, 24)
        sessionIdStore.reset.call(ctx)
        isNew = true
      }
  
      // get the originHash
      const originalHash = !isNew && hash(session)
  
      return {
        originalHash: originalHash,
        session: session,
        isNew: isNew
      }
    }
docs: get session from store
  get sessionId from cookie
  save sessionId into context
  get session from store