действительно ли это - хорошая идея создать перечисление для ключевых названий значений сессии?

Вопрос, который вы связали , касается данных , а не соединений. Многопользовательская работа с глобальными данными нецелесообразна, потому что вы не можете понять, где эти сотрудники находятся в веб-приложении, чтобы синхронизировать их.

Решение этого вопроса заключается в использовании внешнего источника данных, такого как база данных, к которой необходимо каким-либо образом подключиться. Однако ваша идея иметь одно глобальное соединение небезопасна, поскольку несколько рабочих потоков будут взаимодействовать с ним одновременно и либо связываться друг с другом, либо ждать по одному для получения ресурса. Самый простой способ справиться с этим - установить соединение в каждом представлении, когда вам это нужно.


В этом примере показано, как создать уникальное соединение для каждого запроса без глобальных значений, повторно использовать соединение после его установления для запроса. Объект g, хотя и выглядит как глобальный, реализован как локальный поток за кулисами, поэтому каждый работник получает свой собственный экземпляр g и соединение, сохраненное в нем только во время одного запроса.

from flask import g

def get_conn():
    """Use this function to establish or get the already established
    connection during a request. The connection is closed at the end
    of the request. This avoids having a global connection by storing
    the connection on the g object per request.
    """
    if "conn" not in g:
        g.conn = make_connection(...)

    return g.conn

@app.teardown_request
def close_conn(e):
    """Automatically close the connection after the request if
    it was opened.
    """
    conn = g.pop("conn", None)

    if conn is not None:
        conn.close()

@app.route("/get_data")
def get_data():
    # If something else has already used get_conn during the
    # request, this will return the same connection. Anything
    # that uses it after this will also use the same connection.
    conn = get_conn()
    data = conn.query(...)
    return jsonify(data)

Вы можете со временем обнаружить, что установление нового соединения для каждого запроса является слишком дорогим, если у вас есть много тысяч одновременных запросов. Одним из решений является создание пула соединений для глобального хранения списка соединений с поточно-ориентированным способом получения и замены соединения в списке по мере необходимости. SQLAlchemy (и Flask-SQLAlchemy) использует эту технику. Многие библиотеки уже предоставляют реализации пула соединений, поэтому либо используйте их, либо используйте их в качестве справочного для своего.

9
задан M4N 21 January 2009 в 18:15
поделиться

6 ответов

Вместо того, чтобы использовать константы для сеансовых ключей, я использую свой собственный безопасный с точки зрения типов объект сессии, который похож на это (извините, это находится в C#, посмотрите ниже для версии VB):

public class MySession
{
  // Private constructor (use MySession.Current to access the current instance).
  private MySession() {}

  // Gets the current session.
  public static MySession Current
  {
    get
    {
      MySession session = HttpContext.Current.Session["__MySession__"] as MySession;
      if (session == null)
      {
        session = new MySession();
        HttpContext.Current.Session["__MySession__"] = session;
      }
      return session;
    }
  }

  // My session data goes here:
  public string MyString { get; set; };
  public bool MyFlag { get; set; };
  public int MyNumber { get; set; };
}

Каждый раз, когда мне нужно к чтению-записи что-то к/от сессии, я могу использовать свой безопасный с точки зрения типов объект сессии как это:

string s = MySession.Current.MyString;
s = "new value";
MySession.Current.MyString = s;

Это решение приводит к нескольким преимуществам:

  • У меня есть безопасная с точки зрения типов Сессия (больше никаких преобразований типа)
  • Я могу зарегистрировать все основанные на сессии данные (путем комментария общественных собственностей в MySession)
  • При добавлении нового элемента к сессии я не должен искать решение проверить, использовался ли тот же сеансовый ключ уже где-то в другом месте.

Обновление: вот версия VB (автоматически преобразована из версии C#). Извините, но я не знаю VB и таким образом, я не знал, как записать свойства в VB:

Public Class MySession
    ' Private constructor (use MySession.Current to access the current instance).
    Private Sub New()
    End Sub

    ' Gets the current session.
    Public Shared ReadOnly Property Current() As MySession
        Get
            Dim session As MySession = TryCast(HttpContext.Current.Session("__MySession__"), MySession)
            If session = Nothing Then
                session = New MySession()
                HttpContext.Current.Session("__MySession__") = session
            End If
            Return session
        End Get
    End Property

    ' My session data goes here:
    Public MyString As String
    Public MyFlag As Boolean
    Public MyNumber As Integer
End Class
17
ответ дан 4 December 2019 в 07:24
поделиться

Как насчет:-

public static class  SessionVar
{
  public static readonly string myVar1 = "myVar1";
  public static readonly string myVar2 = "myVar2";
  public static readonly string myVar3 = "myVar3";
  public static readonly string myVar4 = "myVar4";
}

Это позволяет Вам использовать:-

session(SessionVar.myVar1) = something;
4
ответ дан 4 December 2019 в 07:24
поделиться

Я использовал классы как это для создания введенной обертки сессии/кэша. Вы, возможно, должны добавить дополнительный код к получению/устанавливанию, но я оставлю это до Вас.

internal class SessionHelper
{
    private const string  myVar1Key = "myvar1";

    public static int MyVar1
    {
        get
        {
            return (int)System.Web.HttpContext.Current.Session[myVar1Key];
        }
        set
        {
            System.Web.HttpContext.Current.Session[myVar1Key] = value;
        }
    }
}

Извините за C#....

0
ответ дан 4 December 2019 в 07:24
поделиться

Только если те значения связаны. Иначе используйте простые константы.

9
ответ дан 4 December 2019 в 07:24
поделиться

Для простой вещи удаления всех ссылок строкового ключа я пошел бы с глобальными статическими/общими константами, видимыми в области действия приложения.

Иначе простая обертка со строгим контролем типов для переменных сеанса является превосходящей альтернативой, и это - намного больше благоприятного для ООП рассмотрения, что Вы получаете совместимость Обозревателя объектов и intellisense.

Единственный путь I видит, что перечислимое быть много ценности должно использоваться для индексации в массив или подобный список. Но даже затем необходимо бросить перечисление к интервалу.

Так, у Вас мог быть массив, который Вы загружаете при запуске приложения всеми своими ключами переменной сеанса и затем перечислением для индексов. Однако, учитывая, что объект Сессии происходит из HttpSessionState, который происходит из IEnumerable, необходимо смочь просто сделать цикл foreach по переменным сеанса, если Вы должны.

0
ответ дан 4 December 2019 в 07:24
поделиться

Я понимаю, что этот вопрос был задан некоторое время назад и "ответ" уже был выбран. Но я просто наткнулся на него. Ответ Мартина хорош. Однако, чтобы помочь любому, кто наткнётся на это в будущем, если вы действительно хотите иметь дело с Сессией, прочтите этот пост . Не думаю, что вы найдете что-то проще.

0
ответ дан 4 December 2019 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: