来源: stackexchange

问:
Uvicorn async workers are still working synchronously
Question in short

I have migrated my project from Django 2.2 to Django 3.2, and now I want to start using the possibility for asynchronous views. I have created an async view, setup asgi configuration, and run gunicorn with a Uvicorn worker. When swarming this server with 10 users concurrently, they are served synchronously. What do I need to configure in order to serve 10 concurrent users an async view?

Question in detail

This is what I did so far in my local environment:

I am working with Django 3.2.10 and Python 3.9.

I have installed gunicorn and uvicorn through pip

I have created an asgi.py file with the following contents

```<code>    import os
    from django.core.asgi import get_asgi_application
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyService.settings.local')
    application = get_asgi_application()
</code>```

I have created a view with the following implementation, and connected it in urlpatterns:

```<code>    import asyncio
    import json
    from django.http import HttpResponse

    async def async_sleep(request):
        await asyncio.sleep(1)
        return HttpResponse(json.dumps({'mode': 'async', 'time': 1).encode())
</code>```

I run locally a gunicorn server with a Uvicorn worker:

```<code>gunicorn MyService.asgi:application -k uvicorn.workers.UvicornWorker
[2022-01-26 14:37:14 +0100] [8732] [INFO] Starting gunicorn 20.1.0
[2022-01-26 14:37:14 +0100] [8732] [INFO] Listening at: http://127.0.0.1:8000 (8732)
[2022-01-26 14:37:14 +0100] [8732] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2022-01-26 14:37:14 +0100] [8733] [INFO] Booting worker with pid: 8733
[2022-01-26 13:37:15 +0000] [8733] [INFO] Started server process [8733]
[2022-01-26 13:37:15 +0000] [8733] [INFO] Waiting for application startup.
[2022-01-26 13:37:15 +0000] [8733] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2022-01-26 13:37:15 +0000] [8733] [INFO] Application startup complete.
</code>```

I hit the API from a local client once. After 1 second, I get a 200 OK, as expected.

I set up a locust server to spawn concurrent users. When I let it make requests with 1 concurrent user, every 1 second an API call is completed.

When I let it make requests with 10 concurrent users, every 1 second an API call is completed. All other requests are waiting.

This last thing is not what I expect. I expect the worker, while sleeping asynchronously, to pick up the next request already. Am I missing some configuration?

I also tried it by using Daphne instead of Uvicorn, but with the same result.

Locust

This is how I have set up my locust.

Start a new virtualenv

pip install locust

Create a locustfile.py with the following content:

```<code>from locust import HttpUser, task
class SleepUser(HttpUser):
    @task
    def async_sleep(self):
        self.client.get('/api/async_sleep/')
</code>```

Run the locust executable from the shell

Visit http://0.0.0.0:8089 in the browser

Set number of workers to 10, spawn rate to 1 and host to http://127.0.0.1:8000

Middleware

These are my middleware settings

```<code>MIDDLEWARE = [
    'django_prometheus.middleware.PrometheusBeforeMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'shared.common.middleware.ApiLoggerMiddleware',
    'django_prometheus.middleware.PrometheusAfterMiddleware',
]
</code>```

The ApiLoggerMiddleware from shared is from our own code, I will investigate this one first. This is the implementation of it.

```<code>import logging
import os
from typing import List

from django.http import HttpRequest, HttpResponse
from django.utils import timezone

from shared.common.authentication_service import BaseAuthenticationService

class ApiLoggerMiddleware:
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        self.request_time = None
        self.response_time = None

    def __call__(self, request: HttpRequest) -> HttpResponse:
        common_data = self.on_request(request)
        response = self._get_response(request)
        self.on_response(response, common_data)
        return response

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    def on_request(self, request: HttpRequest) -> List[str]:
        self.request_time = timezone.now()

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
                      "IN",
                      str(self.pid),
                      str(self.request_time),
                  ] + common + [
                      self.truncate_body(request)
                  ]

        self.logger.info(', '.join(in_line))
        return common

    def on_response(self, response: HttpResponse, common: List[str]) -> None:
        self.response_time = timezone.now()

        out_line = [
                       "OUT",
                       str(self.pid),
                       str(self.response_time)
                   ] + common + [
                       str(self.response_time - self.request_time),
                       str(response.status_code),
                   ]
        self.logger.info(", ".join(out_line))

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')
</code>```

Sources

Sources I have used:

A Guide to ASGI in Django 3.0 and its performance

How to use Django with Uvicorn

答:
Your ApiLoggerMiddleware is a synchronous middleware.

From https://docs.djangoproject.com/en/4.0/topics/async/#async-views, emphasis mine:

You will only get the benefits of a fully-asynchronous request stack if you have no synchronous middleware loaded into your site. If there is a piece of synchronous middleware, then Django must use a thread per request to safely emulate a synchronous environment for it.

Middleware can be built to support both sync and async contexts. Some of Django’s middleware is built like this, but not all. To see what middleware Django has to adapt, you can turn on debug logging for the django.request logger and look for log messages about “Synchronous middleware … adapted”.

(The log message currently says "Asynchronous middleware ... adapted", bug reported at #33495.)

Turn on debug logging for the django.request logger  by adding this to your LOGGING setting:

'django.request': {
    'handlers': ['console'],
    'level': 'DEBUG',
},
```
<h1>Solution</h1>
<p>To make <code>ApiLoggerMiddleware</code> asynchronous:</p>
<ol>
<li>Inherit <code>django.utils.deprecation.MiddlewareMixin</code>.
<ul>
<li>call <code>super().__init__(get_response)</code> in <code>__init__</code>.</li>
<li>remove <code>__call__</code>; <code>MiddlewareMixin.__call__</code> makes your middleware asynchronous.</li>
</ul>
</li>
<li>Refactor <code>on_request</code> to <code>process_request</code>.
<ul>
<li>return <code>None</code> instead of <code>common</code>.</li>
<li>attach <code>common</code> to <code>request</code> instead: <code>request.common = common</code>.<br />
remember to update references to <code>request.common</code>.</li>
<li>attach <code>request_time</code> to <code>request</code> instead of <code>self</code> to make it (and the middleware) thread-safe.<br />
remember to update references to <code>request.request_time</code>.</li>
</ul>
</li>
<li>Refactor <code>on_response(self, response, common)</code> to <code>process_response(self, request, response)</code>.
<ul>
<li>return <code>response</code>.</li>
<li>don't attach <code>response_time</code> to <code>self</code>; leave it as a variable since it's not used in other functions.</li>
</ul>
</li>
</ol>
<p>The result:</p>
<pre class="lang-py prettyprint-override"><code>class ApiLoggerMiddleware(MiddlewareMixin):
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        super().__init__(get_response)  # +
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        # self.request_time = None   # -
        # self.response_time = None  # -

    # def __call__(self, request: HttpRequest) -> HttpResponse:  # -
    #     common_data = self.on_request(request)                 # -
    #     response = self._get_response(request)                 # -
    #     self.on_response(response, common_data)                # -
    #     return response                                        # -

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    # def on_request(self, request: HttpRequest) -> List[str]:  # -
    def process_request(self, request: HttpRequest) -> None:    # +
        # self.request_time = timezone.now()   # -
        request.request_time = timezone.now()  # +

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
            "IN",
            str(self.pid),
            # str(self.request_time),   # -
            str(request.request_time),  # +
        ] + common + [
            self.truncate_body(request)
        ]

        self.logger.info(', '.join(in_line))
        # return common          # -
        request.common = common  # +
        return None              # +

    # def on_response(self, response: HttpResponse, common: List[str]) -> None:                # -
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:  # +
        # self.response_time = timezone.now()  # -
        response_time = timezone.now()         # +

        out_line = [
            "OUT",
            str(self.pid),
            # str(self.response_time)  # -
            str(response_time)         # +
            # ] + common + [                    # -
        ] + getattr(request, 'common', []) + [  # +
            # str(self.response_time - self.request_time),             # -
            str(response_time - getattr(request, 'request_time', 0)),  # +
            str(response.status_code),
        ]
        self.logger.info(", ".join(out_line))
        return response  # +

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')
</code>```

ContentLicense: CC BY-SA 4.0

Body:
Question in short

I have migrated my project from Django 2.2 to Django 3.2, and now I want to start using the possibility for asynchronous views. I have created an async view, setup asgi configuration, and run gunicorn with a Uvicorn worker. When swarming this server with 10 users concurrently, they are served synchronously. What do I need to configure in order to serve 10 concurrent users an async view?

Question in detail

This is what I did so far in my local environment:

I am working with Django 3.2.10 and Python 3.9.

I have installed gunicorn and uvicorn through pip

I have created an asgi.py file with the following contents

    import os
    from django.core.asgi import get_asgi_application
    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyService.settings.local')
    application = get_asgi_application()

I have created a view with the following implementation, and connected it in urlpatterns:

    import asyncio
    import json
    from django.http import HttpResponse

    async def async_sleep(request):
        await asyncio.sleep(1)
        return HttpResponse(json.dumps({'mode': 'async', 'time': 1).encode())

I run locally a gunicorn server with a Uvicorn worker:

gunicorn MyService.asgi:application -k uvicorn.workers.UvicornWorker
[2022-01-26 14:37:14 +0100] [8732] [INFO] Starting gunicorn 20.1.0
[2022-01-26 14:37:14 +0100] [8732] [INFO] Listening at: http://127.0.0.1:8000 (8732)
[2022-01-26 14:37:14 +0100] [8732] [INFO] Using worker: uvicorn.workers.UvicornWorker
[2022-01-26 14:37:14 +0100] [8733] [INFO] Booting worker with pid: 8733
[2022-01-26 13:37:15 +0000] [8733] [INFO] Started server process [8733]
[2022-01-26 13:37:15 +0000] [8733] [INFO] Waiting for application startup.
[2022-01-26 13:37:15 +0000] [8733] [INFO] ASGI 'lifespan' protocol appears unsupported.
[2022-01-26 13:37:15 +0000] [8733] [INFO] Application startup complete.

I hit the API from a local client once. After 1 second, I get a 200 OK, as expected.

I set up a locust server to spawn concurrent users. When I let it make requests with 1 concurrent user, every 1 second an API call is completed.

When I let it make requests with 10 concurrent users, every 1 second an API call is completed. All other requests are waiting.

This last thing is not what I expect. I expect the worker, while sleeping asynchronously, to pick up the next request already. Am I missing some configuration?

I also tried it by using Daphne instead of Uvicorn, but with the same result.

Locust

This is how I have set up my locust.

Start a new virtualenv

pip install locust

Create a locustfile.py with the following content:

from locust import HttpUser, task
class SleepUser(HttpUser):
    @task
    def async_sleep(self):
        self.client.get('/api/async_sleep/')

Run the locust executable from the shell

Visit http://0.0.0.0:8089 in the browser

Set number of workers to 10, spawn rate to 1 and host to http://127.0.0.1:8000

Middleware

These are my middleware settings

MIDDLEWARE = [
    'django_prometheus.middleware.PrometheusBeforeMiddleware',
    'corsheaders.middleware.CorsMiddleware',
    'django.middleware.gzip.GZipMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    'django.middleware.security.SecurityMiddleware',
    'shared.common.middleware.ApiLoggerMiddleware',
    'django_prometheus.middleware.PrometheusAfterMiddleware',
]

The ApiLoggerMiddleware from shared is from our own code, I will investigate this one first. This is the implementation of it.

import logging
import os
from typing import List

from django.http import HttpRequest, HttpResponse
from django.utils import timezone

from shared.common.authentication_service import BaseAuthenticationService

class ApiLoggerMiddleware:
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        self.request_time = None
        self.response_time = None

    def __call__(self, request: HttpRequest) -> HttpResponse:
        common_data = self.on_request(request)
        response = self._get_response(request)
        self.on_response(response, common_data)
        return response

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    def on_request(self, request: HttpRequest) -> List[str]:
        self.request_time = timezone.now()

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
                      "IN",
                      str(self.pid),
                      str(self.request_time),
                  ] + common + [
                      self.truncate_body(request)
                  ]

        self.logger.info(', '.join(in_line))
        return common

    def on_response(self, response: HttpResponse, common: List[str]) -> None:
        self.response_time = timezone.now()

        out_line = [
                       "OUT",
                       str(self.pid),
                       str(self.response_time)
                   ] + common + [
                       str(self.response_time - self.request_time),
                       str(response.status_code),
                   ]
        self.logger.info(", ".join(out_line))

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')

Sources

Sources I have used:

A Guide to ASGI in Django 3.0 and its performance

How to use Django with Uvicorn

Body:
Your ApiLoggerMiddleware is a synchronous middleware.

From https://docs.djangoproject.com/en/4.0/topics/async/#async-views, emphasis mine:

You will only get the benefits of a fully-asynchronous request stack if you have no synchronous middleware loaded into your site. If there is a piece of synchronous middleware, then Django must use a thread per request to safely emulate a synchronous environment for it.

Middleware can be built to support both sync and async contexts. Some of Django’s middleware is built like this, but not all. To see what middleware Django has to adapt, you can turn on debug logging for the django.request logger and look for log messages about “Synchronous middleware … adapted”.

(The log message currently says "Asynchronous middleware ... adapted", bug reported at #33495.)

Turn on debug logging for the django.request logger  by adding this to your LOGGING setting:

'django.request': {
    'handlers': ['console'],
    'level': 'DEBUG',
},

Solution

To make ApiLoggerMiddleware asynchronous:

Inherit django.utils.deprecation.MiddlewareMixin.

call super().__init__(get_response) in __init__.

remove __call__; MiddlewareMixin.__call__ makes your middleware asynchronous.

Refactor on_request to process_request.

return None instead of common.

attach common to request instead: request.common = common.

remember to update references to request.common.

attach request_time to request instead of self to make it (and the middleware) thread-safe.

remember to update references to request.request_time.

Refactor on_response(self, response, common) to process_response(self, request, response).

return response.

don't attach response_time to self; leave it as a variable since it's not used in other functions.

The result:

class ApiLoggerMiddleware(MiddlewareMixin):
    TOO_BIG_FOR_LOG_BYTES = 2 * 1024

    def __init__(self, get_response):
        # The get_response callable is provided by Django, it is a function
        # that takes a request and returns a response. Plainly put, once we're
        # done with the incoming request, we need to pass it along to get the
        # response which we need to ultimately return.
        super().__init__(get_response)  # +
        self._get_response = get_response
        self.logger = logging.getLogger('api')
        self.pid = os.getpid()
        # self.request_time = None   # -
        # self.response_time = None  # -

    # def __call__(self, request: HttpRequest) -> HttpResponse:  # -
    #     common_data = self.on_request(request)                 # -
    #     response = self._get_response(request)                 # -
    #     self.on_response(response, common_data)                # -
    #     return response                                        # -

    def truncate_body(self, request: HttpRequest) -> str:
        return f"{request.body[:self.TOO_BIG_FOR_LOG_BYTES]}"

    # def on_request(self, request: HttpRequest) -> List[str]:  # -
    def process_request(self, request: HttpRequest) -> None:    # +
        # self.request_time = timezone.now()   # -
        request.request_time = timezone.now()  # +

        remote_address = self.get_remote_address(request)
        user_agent = request.headers.get('User-Agent') or ''
        customer_uuid = self.get_customer_from_request_auth(request)
        method = request.method
        uri = request.get_raw_uri()

        common = [
            remote_address,
            user_agent,
            customer_uuid,
            method,
            uri
        ]

        in_line = [
            "IN",
            str(self.pid),
            # str(self.request_time),   # -
            str(request.request_time),  # +
        ] + common + [
            self.truncate_body(request)
        ]

        self.logger.info(', '.join(in_line))
        # return common          # -
        request.common = common  # +
        return None              # +

    # def on_response(self, response: HttpResponse, common: List[str]) -> None:                # -
    def process_response(self, request: HttpRequest, response: HttpResponse) -> HttpResponse:  # +
        # self.response_time = timezone.now()  # -
        response_time = timezone.now()         # +

        out_line = [
            "OUT",
            str(self.pid),
            # str(self.response_time)  # -
            str(response_time)         # +
            # ] + common + [                    # -
        ] + getattr(request, 'common', []) + [  # +
            # str(self.response_time - self.request_time),             # -
            str(response_time - getattr(request, 'request_time', 0)),  # +
            str(response.status_code),
        ]
        self.logger.info(", ".join(out_line))
        return response  # +

    @classmethod
    def get_customer_from_request_auth(cls, request: HttpRequest) -> str:
        token = request.headers.get('Authorization')
        if not token:
            return 'no token'
        try:
            payload = BaseAuthenticationService.validate_access_token(token)
            return payload.get('amsOrganizationId', '')
        except Exception:
            return 'unknown'

    @classmethod
    def get_remote_address(cls, request: HttpRequest) -> str:
        if 'X-Forwarded-For' in request.headers:
            # in case the request comes in through a proxy, the remote address
            # will be just the last proxy that passed it along, that's why we
            # have to get the remote from X-Forwarded-For
            # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For
            addresses = request.headers['X-Forwarded-For'].split(',')
            client = addresses[0]
            return client
        else:
            return request.META.get('REMOTE_ADDR', '')


问:
UITableView image on the left hand side

Possible Duplicate:

  adding images to UItableView

I want to add image in UITableView in the left hand side how could I add it?

答:
In the cellForRowAtIndexPath method add:

```<code>cell.imageView.image = [UIImage imageNamed:@"img.png"];
</code>```

and thats it! really easy!

If you are using custom cells then you need to add an ImageView to your custom cell in IB. Then create, connect and synthesize an IBOutlet for it and add this code to the cellForRowAtIndexPath method:

```<code>cell.yourImageOutlet.image = [UIImage imageNamed:@"img.png"];
</code>```

ContentLicense: CC BY-SA 3.0

Title: UITableView image on the left hand side

Body:
In the cellForRowAtIndexPath method add:

cell.imageView.image = [UIImage imageNamed:@"img.png"];

and thats it! really easy!

If you are using custom cells then you need to add an ImageView to your custom cell in IB. Then create, connect and synthesize an IBOutlet for it and add this code to the cellForRowAtIndexPath method:

cell.yourImageOutlet.image = [UIImage imageNamed:@"img.png"];


问:
How to ensure that JMSTemplate caches consumer i.e. com.ibm.mq.jms.MQQueueReceiver?
I am facing a scenario where the reply queue I connect to, runs out of handles. I have traced it to the fact that my JMS Producers are being cached but not my JMS consumers. I am able to send and receive messages just fine so there is no problem with connecting-sending-receiving to/from the queues. I am using the CachedConnectionFactory (SessionCacheSize = 10)with the target factory as com.ibm.mq.jms.MQQueueConnectionFactory while instantiating the jmsTemplate. Code snippet is as follows

            :
            :
            String replyQueue = "MyQueue";// replyQueue which runs out of handles
            messageCreator.setReplyToQueue(new MQQueue(replyQueue));

            jmsTemplate.setReceiveTimeout(receiveTimeout);

            jmsTemplate.send(destination, messageCreator);// Send to destination queue
            Message message = jmsTemplate.receiveSelected(replyQueue,
                  String.format("JMSCorrelationID = '%s'", messageCreator.getMessageId()));
            :
            :
```
<p>From the logs (jms TRACE is enabled) Producer is cached, so the <code>destination</code> queue "handle count" does not increase.</p>
<p>// The first time around (for Producer)</p>
```Registering cached JMS MessageProducer for destination[queue:///<destination>:com.ibm.mq.jms.MQQueueSender@c9x758b
```
<p>// Second time around, the cached producer is reused</p>
```Found cached JMS MessageProducer for destination [queue:///<destination>]: com.ibm.mq.jms.MQQueueSender@c9x758b
```
<p>However, the handles for the replyQueue keep increasing because for every call to that queue, I see a new JMS Consumer being registered. Ultimately the calls to open the replyQueue fail because of MQRC_HANDLE_NOT_AVAILABLE</p>
<p>// First time around</p>
```Registering cached JMS MessageConsumer for destination [queue:///<replyQueue>]:com.ibm.mq.jms.MQQueueReceiver@b3ytd25b
```
<p>// Second time around, another MessageConsumer is registered !</p>
```Registering cached JMS MessageConsumer for destination [queue:///<replyQueue>]:com.ibm.mq.jms.MQQueueReceiver@re25b
```

答:
My memory is a bit dim on this, but here is what is happening.  You are receiving messages based on a message selector.  This selector is always changing, however.   As a test, either remove the selector or make it a constant and see what happens.  So when you try to cache/pool based on connection/session/consumer, the consumer is always changing.  This requires a new cache entry.

After you go through your 10 sessions, a new connection will be created, but the existing one is not closed.  Increase your session count to 100, for example, and your connection count on the MQ broker should climb 10 time slower.

You need to create a new consumer for every message receive as your correlation ID is always changing.  So just cache connection/session.  No matter what you do, you will always have to round trip to the broker to ask for the new correlation ID.

Body:
I am facing a scenario where the reply queue I connect to, runs out of handles. I have traced it to the fact that my JMS Producers are being cached but not my JMS consumers. I am able to send and receive messages just fine so there is no problem with connecting-sending-receiving to/from the queues. I am using the CachedConnectionFactory (SessionCacheSize = 10)with the target factory as com.ibm.mq.jms.MQQueueConnectionFactory while instantiating the jmsTemplate. Code snippet is as follows

            :
            :
            String replyQueue = "MyQueue";// replyQueue which runs out of handles
            messageCreator.setReplyToQueue(new MQQueue(replyQueue));

            jmsTemplate.setReceiveTimeout(receiveTimeout);

            jmsTemplate.send(destination, messageCreator);// Send to destination queue
            Message message = jmsTemplate.receiveSelected(replyQueue,
                  String.format("JMSCorrelationID = '%s'", messageCreator.getMessageId()));
            :
            :

From the logs (jms TRACE is enabled) Producer is cached, so the destination queue "handle count" does not increase.

// The first time around (for Producer)

Registering cached JMS MessageProducer for destination[queue:///<destination>:com.ibm.mq.jms.MQQueueSender@c9x758b

// Second time around, the cached producer is reused

Found cached JMS MessageProducer for destination [queue:///<destination>]: com.ibm.mq.jms.MQQueueSender@c9x758b

However, the handles for the replyQueue keep increasing because for every call to that queue, I see a new JMS Consumer being registered. Ultimately the calls to open the replyQueue fail because of MQRC_HANDLE_NOT_AVAILABLE

// First time around

Registering cached JMS MessageConsumer for destination [queue:///<replyQueue>]:com.ibm.mq.jms.MQQueueReceiver@b3ytd25b

// Second time around, another MessageConsumer is registered !

Registering cached JMS MessageConsumer for destination [queue:///<replyQueue>]:com.ibm.mq.jms.MQQueueReceiver@re25b


问:
Allow any AWS resource from an account to publish to an SQS queue
According to the AWS documentation, this policy allows any S3 bucket to send a notification to an SNS topic:

```<code>{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sns:Publish",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Topic",
            "Condition":{
               "StringEquals":{
                  "AWS:SourceAccount":"444455556666"
                }
            }
        }
    ]
}
</code>```

I want to do the same for an SQS queue instead of an SNS topic. This Policy doesn't work:

```<code>{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:111122223333:*"
                }
            }
        }
    ]
}
</code>```

This (allowing every AWS account in the world) works:

```<code>{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:*:*"
                }
            }
        }
    ]
}
</code>```

But when I try to restrict it with the Principal, it doesn't work again:

```<code>{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"111122223333",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:*:*"
                }
            }
        }
    ]
}
</code>```

By "doesn't work" I mean that the Policy is accepted as valid, but when I try to configure an S3 bucket to send a notification (NotificationConfiguration) I get the error:

```<code>Unable to validate the following destination configurations : Permissions on the destination queue do not allow S3 to publish notifications from this bucket
</code>```

答:
If you want to restricts access to specific AWS account, you need to add nested block AWS under Principal:

```<code>"Principal": {
  "AWS": "111122223333"
},
</code>```

or with multiple accounts:

```<code>"Principal" : {
  "AWS": [
    "123456789012",
    "555555555555"
  ]
}
</code>```

See AWS JSON policy elements: Principal for details.

Body:
According to the AWS documentation, this policy allows any S3 bucket to send a notification to an SNS topic:

{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sns:Publish",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Topic",
            "Condition":{
               "StringEquals":{
                  "AWS:SourceAccount":"444455556666"
                }
            }
        }
    ]
}

I want to do the same for an SQS queue instead of an SNS topic. This Policy doesn't work:

{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:111122223333:*"
                }
            }
        }
    ]
}

This (allowing every AWS account in the world) works:

{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"*",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:*:*"
                }
            }
        }
    ]
}

But when I try to restrict it with the Principal, it doesn't work again:

{
    "Version":"2012-10-17",
    "Id":"MyAWSPolicy",
    "Statement" :[
        {
            "Sid":"My-statement-id",
            "Effect":"Allow",
            "Principal" :"111122223333",
            "Action":"sqs:SendMessage",
            "Resource":"arn:aws:sns:us-east-1:111122223333:My-Queue",
            "Condition":{
               "ArnLike":{
                  "aws:SourceArn":"arn:aws:s3:*:*:*"
                }
            }
        }
    ]
}

By "doesn't work" I mean that the Policy is accepted as valid, but when I try to configure an S3 bucket to send a notification (NotificationConfiguration) I get the error:

Unable to validate the following destination configurations : Permissions on the destination queue do not allow S3 to publish notifications from this bucket

Body:
If you want to restricts access to specific AWS account, you need to add nested block AWS under Principal:

"Principal": {
  "AWS": "111122223333"
},

or with multiple accounts:

"Principal" : {
  "AWS": [
    "123456789012",
    "555555555555"
  ]
}

See AWS JSON policy elements: Principal for details.


问:
Make the background of a flex until the end of the flex
So, I need the background of the flexbox to continue past the screen width, with the scroll. I can't attribute overflow:auto to .elements or .line1/2 because I want the scrollbar at the bottom of the screen (because it's a simplified version of a complicated project).

.line1{
    display: flex;
    flex-flow:row;
    background-color: red;
}
.line2{
    display: flex;
    flex-flow:row;
    background-color: blue;
}
.elements{
    display: flex;
    flex-flow:column;
    background-color: red;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="elements">
  <div class="line1">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
  <div class="line2">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
</div></code>```

答:
Set .elements as inline-flex:

.elements {
  display: inline-flex;
  flex-flow: column;
  background-color: red;
}

.line1 {
  display: flex;
  flex-flow: row;
  background-color: red;
}

.line2 {
  display: flex;
  flex-flow: row;
  background-color: blue;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="elements">
  <div class="line1">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
  <div class="line2">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
</div></code>```

Body:
So, I need the background of the flexbox to continue past the screen width, with the scroll. I can't attribute overflow:auto to .elements or .line1/2 because I want the scrollbar at the bottom of the screen (because it's a simplified version of a complicated project).

.line1{
    display: flex;
    flex-flow:row;
    background-color: red;
}
.line2{
    display: flex;
    flex-flow:row;
    background-color: blue;
}
.elements{
    display: flex;
    flex-flow:column;
    background-color: red;
}

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

HiMyNameIsRickAstley

Body:
Set .elements as inline-flex:

.elements {
  display: inline-flex;
  flex-flow: column;
  background-color: red;
}

.line1 {
  display: flex;
  flex-flow: row;
  background-color: red;
}

.line2 {
  display: flex;
  flex-flow: row;
  background-color: blue;
}

<div class="elements">
  <div class="line1">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
  <div class="line2">
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
    <h1>HiMyNameIsRickAstley</h1>
  </div>
</div>


问:
How do I use .Value to get cell value and search for another cell w same value?
So I am computing a date 18 months out from start date then deleting every column after 18 months.

E2 is where I currently store the calculated 18 months out value.
So this week, 18 months out is 7/24/2023.. I need this to search for 7/24/2023 in row 1, find it, then delete every column after.

```<code>Range(Cells(1, Range("1:1").Find(What:=Range("E2").Value.Column + 1),
_ Cells(1, Cells(1, Columns.Count).End(xlToLeft).Column)).EntireColumn.Delete
</code>```

答:
Your +1 is in the wrong place

When using find() it's best to check you got a match:

Dim f as Range, ws as Worksheet

set ws = Activesheet
Set f = ws.Rows(1).Find(What:=ws.Range("E2").Value)
If Not f Is Nothing then
    ws.Range(f.Offset(0, 1), ws.Cells(1, ws.Columns.count).End(xlToLeft)).EntireColumn.Delete
End if
```

Body:
So I am computing a date 18 months out from start date then deleting every column after 18 months.

E2 is where I currently store the calculated 18 months out value.
So this week, 18 months out is 7/24/2023.. I need this to search for 7/24/2023 in row 1, find it, then delete every column after.

Range(Cells(1, Range("1:1").Find(What:=Range("E2").Value.Column + 1),
_ Cells(1, Cells(1, Columns.Count).End(xlToLeft).Column)).EntireColumn.Delete


问:
Is it possible to create a circular timeline plot with ggplot?
Is it possible to use ggplot to produce a pie chart of a year (or some other period of time) with wedges that correspond to periods set apart by specific dates (that could then be modified using the rest of ggplot's usual tools)?

Here's a cludged sketch of what I think I'm trying to do:

Using the two dates (21 December and 21 March), we could define the purple/blue area to be "winter;" similar things could be done for the other seasons. R already understands dates, so I thought it might be possible for it to plot time periods like this. While this isn't a super-complicated (or even useful) example, I think it could be a useful technique.

答:
We can use geomtextpath to get the circular labels. Let's say we want to plot the seasons, equinoxes and solstices:

library(geomtextpath)

df <- data.frame(date = as.POSIXct(c("2022-03-20 15:33", "2022-06-21 10:13",
                               "2022-09-23 02:03", "2022-12-21 21:47")),
           event = c("Vernal Equinox", "Summer Solstice",
                     "Autumnal Equinox", "Winter Solstice"))

seasons <- data.frame(xmin = c(-Inf, 2/12, 5/12, 8/12, 11/12),
                      xmax = c(2/12, 5/12, 8/12, 11/12, Inf),
                      ymin = 0, ymax = 0.95,
                      season = c("Winter", "Spring", "Summer",
                                 "Autumn", "Winter"))
```
<p>The plotting code might look something like this:</p>
<pre class="lang-r prettyprint-override"><code>ggplot() +
  geom_rect(data = seasons,
            aes(xmin = xmin,xmax = xmax, ymin = ymin, ymax = ymax, fill = season),
            alpha = 0.2) +
  geom_textpath(data = data.frame(x = seq(0.5/13, 12.5/13, length = 12),
                                  y = 1, label = month.name),
                aes(x, y, label = label), size = 6) +
  geom_textpath(data = data.frame(x = c(0.5/12, 3.5/12, 6.5/12, 9.5/12), y = 0.8,
                                  season = c("Winter", "Spring", "Summer", "Autumn")),
                aes(x, y, color = season, label = season), size = 10,
                alpha = 0.5, fontface = 2) +
  geom_hline(yintercept = c(0.95, 1.05)) +
  geom_segment(data = data.frame(x = seq(0, 12/13, length = 12),
    xend = seq(0, 12/13, length = 12),
    y = 0.95, yend = 1.05), aes(x, y, xend = xend, yend = yend)) +
  geom_textsegment(data = df,  aes(x = lubridate::decimal_date(date) %% 1,
                   xend = lubridate::decimal_date(date) %% 1,
                   y = 0, yend = 0.95, label = event), vjust = -0.2) +
  scale_fill_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown")) +
  scale_color_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown")) +
  scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) +
  scale_y_continuous(limits = c(0, 1.05)) +
  coord_polar() +
  theme_void() +
  theme(legend.position = "none")
</code>```

Edit

For the re-creation of the liturgical calendar linked in the comments, we can do something like this:

library(geomtextpath)
library(dplyr)

decimal <- function(x) lubridate::decimal_date(x) %% 1

Seasons <- Seasons %>%
  mutate(Start_Date = decimal(Start_Date),
         End_Date   = decimal(End_Date))
Seasons$Start_Date[1] <- -Inf
Seasons$End_Date[nrow(Seasons)] <- Inf

ggplot(Seasons) +
  geom_rect(aes(xmin = Start_Date, xmax = End_Date,
                ymin = 0, ymax = 0.95, fill = Season)) +
  geom_hline(yintercept = c(0.95, 1.05, 1.07)) +
  geom_segment(data = Separators, aes(x = x, xend = x, y = 0.95, yend = 1.07)) +
  geom_textpath(data = Months, aes(x = Date, y = pos, label = Month),
                fontface = 2) +
  geom_textsegment(data = Events,
                   aes(x = decimal(Date), xend = decimal(Date),
                       y = 0, yend = 0.95, label = Event), vjust = 1.1,
                   hjust = 0.95) +
  geom_textpath(data = data.frame(x = c(0.7, 0.22), y = 0.8,
                label = c("Time after Pentecost", "Lent")),
                aes(x, y, label = label, group = x), spacing = 500) +
  scale_fill_manual(values = Season_Colours) +
  scale_x_continuous(limits = c(0, 1)) +
  coord_polar() +
  theme_void() +
  theme(legend.position = "none",
        plot.title = element_text(hjust = 0.5, face = 2)) +
  ggtitle("THE LITURGICAL YEAR")
```
<p><img src="https://i.stack.imgur.com/1kdER.png" alt="enter image description here" /></p>
<hr />
<p><strong>Liturgical data</strong></p>
<pre class="lang-r prettyprint-override"><code>Events  <- data.frame(Event = c("Epiphany", "Ash Wednesday",
                                "Easter Sunday", "Ascension", "Pentecost",
                                "Trinity Sunday", "1st Sunday of Advent",
                                "Immaculate Conception", "Christmas Day",
                                "Epiphany"),
                      Date  = as.POSIXct(
                        c("2022-01-06", "2022-03-02",
                          "2022-04-17", "2022-05-26", "2022-06-06",
                          "2022-06-12", "2022-11-27", "2022-12-08",
                          "2022-12-25", "2023-01-06")))

Seasons <- data.frame(Season = c("Christmas", "Time after Epiphany",
                      "Septuagesima", "Lent", "Easter",
                      "Pentecost", "Time after Pentecost",
                      "Advent", "Christmas"),
           Start_Date = as.POSIXct(c("2021-12-25",
             "2022-01-06", "2022-02-13", "2022-03-02",
             "2022-04-17", "2022-06-06", "2022-06-12",
             "2022-11-27", "2022-12-25"
           )),
           End_Date = as.POSIXct(c("2022-01-06",
             "2022-02-13", "2022-03-02",
             "2022-04-17", "2022-06-06", "2022-06-12",
             "2022-11-27", "2022-12-25", "2023-01-06"
           )))

Season_Colours <- c(`Time after Epiphany`  = "#7dca64",
                    Septuagesima           = "#896d96",
                    Lent                   = "#896d96",
                    Easter                 = "white",
                    Pentecost              = "#df0f33",
                    `Time after Pentecost` = "#7dca64",
                    Advent                 = "#896d96",
                    Christmas              = "white")

Months <- data.frame(Month = toupper(month.name),
                     Date  = seq(0.5/13, 12.5/13, length = 12),
                     pos   = 1)

Separators <- data.frame(x = seq(0, 12/13, length = 12))
</code>```

Body:
We can use geomtextpath to get the circular labels. Let's say we want to plot the seasons, equinoxes and solstices:

library(geomtextpath)

df <- data.frame(date = as.POSIXct(c("2022-03-20 15:33", "2022-06-21 10:13",
                               "2022-09-23 02:03", "2022-12-21 21:47")),
           event = c("Vernal Equinox", "Summer Solstice",
                     "Autumnal Equinox", "Winter Solstice"))

seasons <- data.frame(xmin = c(-Inf, 2/12, 5/12, 8/12, 11/12),
                      xmax = c(2/12, 5/12, 8/12, 11/12, Inf),
                      ymin = 0, ymax = 0.95,
                      season = c("Winter", "Spring", "Summer",
                                 "Autumn", "Winter"))

The plotting code might look something like this:

ggplot() +
  geom_rect(data = seasons,
            aes(xmin = xmin,xmax = xmax, ymin = ymin, ymax = ymax, fill = season),
            alpha = 0.2) +
  geom_textpath(data = data.frame(x = seq(0.5/13, 12.5/13, length = 12),
                                  y = 1, label = month.name),
                aes(x, y, label = label), size = 6) +
  geom_textpath(data = data.frame(x = c(0.5/12, 3.5/12, 6.5/12, 9.5/12), y = 0.8,
                                  season = c("Winter", "Spring", "Summer", "Autumn")),
                aes(x, y, color = season, label = season), size = 10,
                alpha = 0.5, fontface = 2) +
  geom_hline(yintercept = c(0.95, 1.05)) +
  geom_segment(data = data.frame(x = seq(0, 12/13, length = 12),
    xend = seq(0, 12/13, length = 12),
    y = 0.95, yend = 1.05), aes(x, y, xend = xend, yend = yend)) +
  geom_textsegment(data = df,  aes(x = lubridate::decimal_date(date) %% 1,
                   xend = lubridate::decimal_date(date) %% 1,
                   y = 0, yend = 0.95, label = event), vjust = -0.2) +
  scale_fill_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown")) +
  scale_color_manual(values = c(Winter = "deepskyblue4",
                               Spring = "yellowgreen",
                               Summer = "gold",
                               Autumn = "brown")) +
  scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) +
  scale_y_continuous(limits = c(0, 1.05)) +
  coord_polar() +
  theme_void() +
  theme(legend.position = "none")

Edit

For the re-creation of the liturgical calendar linked in the comments, we can do something like this:

library(geomtextpath)
library(dplyr)

decimal <- function(x) lubridate::decimal_date(x) %% 1

Seasons <- Seasons %>%
  mutate(Start_Date = decimal(Start_Date),
         End_Date   = decimal(End_Date))
Seasons$Start_Date[1] <- -Inf
Seasons$End_Date[nrow(Seasons)] <- Inf

ggplot(Seasons) +
  geom_rect(aes(xmin = Start_Date, xmax = End_Date,
                ymin = 0, ymax = 0.95, fill = Season)) +
  geom_hline(yintercept = c(0.95, 1.05, 1.07)) +
  geom_segment(data = Separators, aes(x = x, xend = x, y = 0.95, yend = 1.07)) +
  geom_textpath(data = Months, aes(x = Date, y = pos, label = Month),
                fontface = 2) +
  geom_textsegment(data = Events,
                   aes(x = decimal(Date), xend = decimal(Date),
                       y = 0, yend = 0.95, label = Event), vjust = 1.1,
                   hjust = 0.95) +
  geom_textpath(data = data.frame(x = c(0.7, 0.22), y = 0.8,
                label = c("Time after Pentecost", "Lent")),
                aes(x, y, label = label, group = x), spacing = 500) +
  scale_fill_manual(values = Season_Colours) +
  scale_x_continuous(limits = c(0, 1)) +
  coord_polar() +
  theme_void() +
  theme(legend.position = "none",
        plot.title = element_text(hjust = 0.5, face = 2)) +
  ggtitle("THE LITURGICAL YEAR")

Liturgical data

Events  <- data.frame(Event = c("Epiphany", "Ash Wednesday",
                                "Easter Sunday", "Ascension", "Pentecost",
                                "Trinity Sunday", "1st Sunday of Advent",
                                "Immaculate Conception", "Christmas Day",
                                "Epiphany"),
                      Date  = as.POSIXct(
                        c("2022-01-06", "2022-03-02",
                          "2022-04-17", "2022-05-26", "2022-06-06",
                          "2022-06-12", "2022-11-27", "2022-12-08",
                          "2022-12-25", "2023-01-06")))

Seasons <- data.frame(Season = c("Christmas", "Time after Epiphany",
                      "Septuagesima", "Lent", "Easter",
                      "Pentecost", "Time after Pentecost",
                      "Advent", "Christmas"),
           Start_Date = as.POSIXct(c("2021-12-25",
             "2022-01-06", "2022-02-13", "2022-03-02",
             "2022-04-17", "2022-06-06", "2022-06-12",
             "2022-11-27", "2022-12-25"
           )),
           End_Date = as.POSIXct(c("2022-01-06",
             "2022-02-13", "2022-03-02",
             "2022-04-17", "2022-06-06", "2022-06-12",
             "2022-11-27", "2022-12-25", "2023-01-06"
           )))

Season_Colours <- c(`Time after Epiphany`  = "#7dca64",
                    Septuagesima           = "#896d96",
                    Lent                   = "#896d96",
                    Easter                 = "white",
                    Pentecost              = "#df0f33",
                    `Time after Pentecost` = "#7dca64",
                    Advent                 = "#896d96",
                    Christmas              = "white")

Months <- data.frame(Month = toupper(month.name),
                     Date  = seq(0.5/13, 12.5/13, length = 12),
                     pos   = 1)

Separators <- data.frame(x = seq(0, 12/13, length = 12))


问:
Laravel 5.4 on PHP 7.0: PDO Exception - Could not find driver (MySQL)
I have a Laravel 5.4 project on my Ubuntu 14.04 (VPS with Plesk 12.5.30). After creating the database and setted up the .env file with required information I ran php artisan migrate and exceptions were thrown:

[Illuminate\Database\QueryException]

    could not find driver (SQL: select * from information_schema.tables where table_schema = pmaramaldb and table_name = migrations)

[PDOException]

    could not find driver

My .env file has:

DB_CONNECTION=mysql

DB_HOST=127.0.0.1

DB_PORT=3306

DB_DATABASE=pmaramaldb

DB_USERNAME=user

DB_PASSWORD=password

I've followed most of the guides to solve this error and there wasn't any positive results:

Enabling Extension Solution:

PDO is enabled

The php.ini file is being generated automatically, I guess this is made by Plesk. At the start of the file it says:

; ATTENTION!

  ;

  ; DO NOT MODIFY THIS FILE BECAUSE IT WAS GENERATED AUTOMATICALLY,

  ; SO ALL YOUR CHANGES WILL BE LOST THE NEXT TIME THE FILE IS GENERATED.

So I've tried it anyway. After that I've restarted Apache and then tried again... Didn't work.

Installing php7.0-mysql Solution:

I've also tried to install MySQL in case is not:

user@server:/var/www/vhosts$ sudo apt-get install php7.0-mysql

Leyendo lista de paquetes... Hecho

Creando árbol de dependencias

Leyendo la información de estado... Hecho

php7.0-mysql is already the newest version.

0 actualizados, 0 se instalarán, 0 para eliminar y 67 no actualizados.

** SQL Lite Install Solution:**

I've also tried as question link says: sudo apt-get install php5-sqlite and the result was:

user@server:/var/www/vhosts/system/maramal.io/etc$ sudo apt-get install php5-sqlite

Leyendo lista de paquetes... Hecho

Creando árbol de dependencias

Leyendo la información de estado... Hecho

php5-sqlite is already the newest version.

0 actualizados, 0 se instalarán, 0 para eliminar y 67 no actualizados.

Composer Dump-autoload Solution:

It didn't work either. I've tried composer dump-autoload and it didn't work.

After ran the command php -i:

PDO

PDO support => enabled

PDO drivers =>

...

PHP Version => 5.6.30-1+deb.sury.org~trusty+1

Well, I am not sure if this has anything to do with the error, but the version shown by running php -v is:

user@server: ~/path$ php -v

PHP 5.6.30-1+deb.sury.org~trusty+1 (cli)

Copyright (c) 1997-2016 The PHP Group

Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies

      with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies

答:
If you are using WSL2, with docker, and recently had an incident with switching db drivers, you could try:</p>
```<code>docker ps (to retrieve your app image)
docker exec <app_code> php artisan cache:clear
docker exec <app_code> php artisan config:clear
</code>```

Body:
If you are using WSL2, with docker, and recently had an incident with switching db drivers, you could try:

docker ps (to retrieve your app image)
docker exec <app_code> php artisan cache:clear
docker exec <app_code> php artisan config:clear


问:
Find certain colons in string using Regex
I'm trying to search for colons in a given string  so as to split the string at the colon for preprocessing based on the following conditions

Preceeded or followed by a word e.g A Book: Chapter 1 or A Book :Chapter 1

Do not match if it is part of emoticons i.e :( or ): or :/ or :-) etc

Do not match if it is part of a given time i.e 16:00 etc

I've come up with a regex as such

(\:)(?=\w)|(?<=\w)(\:)

which satisfies conditions 2 & 3 but still fails on condition 3 as it matches the colon present in the string representation of time. How do I fix this?

edit: it has to be in a single regex statement if possible

答:
You can use

(:\b|\b:)(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b)
```
<p>See the regex demo. <em>Details</em>:</p>
<ul>
<li><code>(:\b|\b:)</code> - Group 1: a <code>:</code> that is either preceded or followed with a word char</li>
<li><code>(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b)</code> - there should be no one or two digits right after <code>:</code> (followed with a word boundary) if the <code>:</code> is preceded with a single or two digits (preceded with a word boundary).</li>
</ul>
<p>Note <code>:\b</code> is equal to <code>:(?=\w)</code> and <code>\b:</code> is equal to <code>(?<=\w):</code>.</p>
<p>If you need to get the same capturing groups as in your original pattern, replace <code>(:\b|\b:)</code> with <code>(?:(:)\b|\b(:))</code>.</p>
<p><strong>More flexible solution</strong></p>
<p>Note that excluding matches can be done with a simpler pattern that matches and <em>captures</em> what you need and just matches what you do not need. This is called "best regex trick ever". So, you may use a regex like</p>
<pre class="lang-none prettyprint-override"><code>8:|:[PD]|\d+(?::\d+)+|(:\b|\b:)
</code>```

that will match 8:, :P, :D, one or more digits and then one or more sequences of : and one or more digits, or will match and capture into Group 1 a : char that is either preceded or followed with a word char. All you need to do is to check if Group 1 matched, and implement required extraction/replacement logic in the code.

Body:
You can use

(:\b|\b:)(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b)

See the regex demo. Details:

(:\b|\b:) - Group 1: a : that is either preceded or followed with a word char

(?!(?:(?<=\b\d:)|(?<=\b\d{2}:))\d{1,2}\b) - there should be no one or two digits right after : (followed with a word boundary) if the : is preceded with a single or two digits (preceded with a word boundary).

Note :\b is equal to :(?=\w) and \b: is equal to (?<=\w):.

If you need to get the same capturing groups as in your original pattern, replace (:\b|\b:) with (?:(:)\b|\b(:)).

More flexible solution

Note that excluding matches can be done with a simpler pattern that matches and captures what you need and just matches what you do not need. This is called "best regex trick ever". So, you may use a regex like

8:|:[PD]|\d+(?::\d+)+|(:\b|\b:)

that will match 8:, :P, :D, one or more digits and then one or more sequences of : and one or more digits, or will match and capture into Group 1 a : char that is either preceded or followed with a word char. All you need to do is to check if Group 1 matched, and implement required extraction/replacement logic in the code.


问:
How to tell JS intellisense code completion that a function returns an object in the same format that it is passed?
I notice that when I use the cloneDeep function supplied by lodash, my code completion figures out that the object being returned uses the same structure as the object being passed in.

However, if I write some custom function that does the same thing, the code completion can not work out that the returned object has the same structure as the one passed in.

I'm not surprised about that, I'm surprised that it DOES work with lodash.cloneDeep! How do they do that? I've looked at the source code and can't see anything obvious. I even stole the JSDoc comment from above cloneDeep and put it above my function, but it doesn't work.

Any ideas?

答:
I believe you need to require the class type you are returning in the file and use a JSDoc style comment above your custom function which defines the return value as the type you are returning.</p>
```<code>const ExampleClass = require('exampleclass')

/**
* My Function
* @returns {ExampleClass}
*/
myFunction () {...}
</code>```

Body:
I believe you need to require the class type you are returning in the file and use a JSDoc style comment above your custom function which defines the return value as the type you are returning.

const ExampleClass = require('exampleclass')

/**
* My Function
* @returns {ExampleClass}
*/
myFunction () {...}


问:
Backbone.js model.save returns TypeError?
I'm trying to implement backbone.js model which looks like this in Django:

```<code>class Booking(models.Model):
    date        = models.DateField('date booked')
    time        = models.TimeField('time booked')
    duration    = models.PositiveSmallIntegerField('duration booked') #x * 15
    user        = models.ForeignKey(User, related_name='bookings')
    room        = models.ForeignKey(Room, related_name='bookings')
    description = models.TextField()
</code>```

It's served through a RESTful interface via TastyPie: /api/booking.
My backbone model is set up like this as per instructions here:

```<code>window.Booking = Backbone.Model.extend({
url     :   function(){
                return this.get('resource_uri') || this.collection.url;
            },
urlRoot :   "/api/booking",
defaults:   {
                user    :   "/api/user/5" //defaults to nobodys
                }
});
window.Bookings = Backbone.Collection.extend({
url         :   BOOKING_API,
parse       :   function(data){
                return data.objects;
            }
});
</code>```

Now trying to test it out in console like this:

```<code>var booking = new Booking({date : "2011-08-17", time: "12:45", duration: 30, room: "/api/room/1", description: "quickbook"});
booking.save();
</code>```

The above code returns a TypeError. I don't see what I'm doing wrong.

答:
You are not defining a resource_uri or putting your booking in a collection.  The TypeError you are seeing is from this.collection.url.  You would see the same error doing booking.collection.url.  Something like the following should do the trick.</p>

```<code>var bookings = new Bookings;
bookings.add(booking);
booking.save();
</code>```

Body:
I'm trying to implement backbone.js model which looks like this in Django:

class Booking(models.Model):
    date        = models.DateField('date booked')
    time        = models.TimeField('time booked')
    duration    = models.PositiveSmallIntegerField('duration booked') #x * 15
    user        = models.ForeignKey(User, related_name='bookings')
    room        = models.ForeignKey(Room, related_name='bookings')
    description = models.TextField()

It's served through a RESTful interface via TastyPie: /api/booking.
My backbone model is set up like this as per instructions here:

window.Booking = Backbone.Model.extend({
url     :   function(){
                return this.get('resource_uri') || this.collection.url;
            },
urlRoot :   "/api/booking",
defaults:   {
                user    :   "/api/user/5" //defaults to nobodys
                }
});
window.Bookings = Backbone.Collection.extend({
url         :   BOOKING_API,
parse       :   function(data){
                return data.objects;
            }
});

Now trying to test it out in console like this:

var booking = new Booking({date : "2011-08-17", time: "12:45", duration: 30, room: "/api/room/1", description: "quickbook"});
booking.save();

The above code returns a TypeError. I don't see what I'm doing wrong.

Body:
You are not defining a resource_uri or putting your booking in a collection.  The TypeError you are seeing is from this.collection.url.  You would see the same error doing booking.collection.url.  Something like the following should do the trick.

var bookings = new Bookings;
bookings.add(booking);
booking.save();


问:
Image is not fitting in PDF document. Using jspdf
This is the code I am using.
My image is quite large. is there a solution to increase page size according to image size in jspdf?</p>
```<code>      var doc = new jsPDF("l", "in", [672, 800]);
      var imgData = canvas.toDataURL("image/png", 1.0);
      doc.setFontSize(40);
      doc.addImage(imgData, "JPEG", 10, 10, 200, 400);
      doc.save("Report.pdf");
    }); ```
</code>```

答:
An image will fit wherever you place it but be constrained by the page size so here I set the page to 25"x25" (63.5 cm x 63.5cm) and once that page is set the image can stretch (or shrink exactly to that size)

It is the placement ratio that decides how much stretch or shrink is seen in either direction. The choice of both sets of units and ratio (page and page object) need to be predetermined for a PDF image rendering.

```<code>var imgData1 = 'data:image/jpeg;base64,/9j/... image is too big for SO ...';

var doc = new jsPDF("l", "pt", [1800, 1800]);

// Build page 1
doc.setPage(1);
doc.setFont('helvetica', 'italic');
doc.setFontSize(40); //Font is Points e.g. 40 pt total but say 4 pt below baseline so set 36 pt down !
doc.text('I am a top left heading on page 1', 0, 36);

// The image is only 500 x 500 pixels (say 1" x 1" @ 500 dpi)
// but lets place it as wide as the page 1800 pts and say 400 pts high.

doc.addImage(imgData1, 'JPG', 0, 50, 1800, 400, "A 500 x 500 pixel Limousine Cat", "none", 0);
doc.addImage(imgData1, 'JPG', 0, 500, 72, 72, "A Postage Stamp Cat", "none", 0);

doc.save('Report.pdf');

</code>```

Note the image was 1" x 1" and now looks streched to 25" HOWEVER inside the PDF it is still only 500x500 unitless pixels so when extracted at say 96dpi it will be declared as 5.208333.." x 5.208333.." so extract at 500dpi to return it to a postage stamp.

The whole point is you set beforehand how the pixels will be utilised in terms of PDF scale and image width to height ratio (forget the normal non PDF concept of dots per inch).

Body:
This is the code I am using.
My image is quite large. is there a solution to increase page size according to image size in jspdf?

      var doc = new jsPDF("l", "in", [672, 800]);
      var imgData = canvas.toDataURL("image/png", 1.0);
      doc.setFontSize(40);
      doc.addImage(imgData, "JPEG", 10, 10, 200, 400);
      doc.save("Report.pdf");
    }); ```

Body:
An image will fit wherever you place it but be constrained by the page size so here I set the page to 25"x25" (63.5 cm x 63.5cm) and once that page is set the image can stretch (or shrink exactly to that size)

It is the placement ratio that decides how much stretch or shrink is seen in either direction. The choice of both sets of units and ratio (page and page object) need to be predetermined for a PDF image rendering.

var imgData1 = 'data:image/jpeg;base64,/9j/... image is too big for SO ...';

var doc = new jsPDF("l", "pt", [1800, 1800]);

// Build page 1
doc.setPage(1);
doc.setFont('helvetica', 'italic');
doc.setFontSize(40); //Font is Points e.g. 40 pt total but say 4 pt below baseline so set 36 pt down !
doc.text('I am a top left heading on page 1', 0, 36);

// The image is only 500 x 500 pixels (say 1" x 1" @ 500 dpi)
// but lets place it as wide as the page 1800 pts and say 400 pts high.

doc.addImage(imgData1, 'JPG', 0, 50, 1800, 400, "A 500 x 500 pixel Limousine Cat", "none", 0);
doc.addImage(imgData1, 'JPG', 0, 500, 72, 72, "A Postage Stamp Cat", "none", 0);

doc.save('Report.pdf');

Note the image was 1" x 1" and now looks streched to 25" HOWEVER inside the PDF it is still only 500x500 unitless pixels so when extracted at say 96dpi it will be declared as 5.208333.." x 5.208333.." so extract at 500dpi to return it to a postage stamp.

The whole point is you set beforehand how the pixels will be utilised in terms of PDF scale and image width to height ratio (forget the normal non PDF concept of dots per inch).


问:
how to add data Labels to seaborn countplot / factorplot
I use python3, seaborn countplot, my question :

how to add the count values for every bar? Show the label at the top of
each bar?

how to have these bars in descending order?

I wrote this:

```<code>fig = plt.figure(figsize=(10,6))
sns.countplot(data_new['district'],data=data_new)
plt.show()
</code>```

Thanks a lot !

答:
If you capture the sns.countplot() return in a variable, you'll be able to set all matplotlib.axes._subplots.AxesSubplot attibutes.

Do like:

```<code>c = sns.countplot(data_new['district'],data=data_new)
</code>```

and then:

```<code>c.set_xlabel('Your X-axis label')
c.set_ylabel('Your Y-axis label')
</code>```

Body:
I use python3, seaborn countplot, my question :

how to add the count values for every bar? Show the label at the top of
each bar?

how to have these bars in descending order?

I wrote this:

fig = plt.figure(figsize=(10,6))
sns.countplot(data_new['district'],data=data_new)
plt.show()

Thanks a lot !

Body:
If you capture the sns.countplot() return in a variable, you'll be able to set all matplotlib.axes._subplots.AxesSubplot attibutes.

Do like:

c = sns.countplot(data_new['district'],data=data_new)

and then:

c.set_xlabel('Your X-axis label')
c.set_ylabel('Your Y-axis label')


问:
Trouble with deploying Tailwind to Heroku
I'm trying to deploy a mini-app styled using Tailwind. It's my first time and I've spent the last two days trying to figure it out. This is the closest I got it to deploying per the error log below. When I test it on my local machine, I'm using commands "npm run build-css" and "live-server public". Using these commands it runs on my local machine just fine but when it comes to deploying to Heroku, I'm getting an error. Per my error log, the status goes from "State changed from starting to crashed" and leaves a code H=10 error. I tried several fixes online via googling what others have done with this type of error but I have had no luck. Any help is much appreciated. Thank you.

In the package.json, this is my script.

```<code>  "scripts": {
    "start": "npm run build:css",
    "build:css": "tailwindcss build src/styles.css -o public/styles.css"
  }
</code>```
```<code>├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── public
│   ├── index.html
│   ├── index.js
│   └── styles.css
└── src
    └── styles.css
</code>```

error log:

https://pastebin.com/tctmPVpU

答:
I've experienced this issue previously and fixed it by ensuring the relevant buildpacks were included.

https://devcenter.heroku.com/articles/buildpacks

Double check that you have the correct buildpacks for your application using this command:

```<code>heroku buildpacks
</code>```

In my case I needed the ruby and node buildpacks, with the node pack preceeding the ruby one.

Body:
I'm trying to deploy a mini-app styled using Tailwind. It's my first time and I've spent the last two days trying to figure it out. This is the closest I got it to deploying per the error log below. When I test it on my local machine, I'm using commands "npm run build-css" and "live-server public". Using these commands it runs on my local machine just fine but when it comes to deploying to Heroku, I'm getting an error. Per my error log, the status goes from "State changed from starting to crashed" and leaves a code H=10 error. I tried several fixes online via googling what others have done with this type of error but I have had no luck. Any help is much appreciated. Thank you.

In the package.json, this is my script.

  "scripts": {
    "start": "npm run build:css",
    "build:css": "tailwindcss build src/styles.css -o public/styles.css"
  }

├── README.md
├── node_modules
├── package-lock.json
├── package.json
├── public
│   ├── index.html
│   ├── index.js
│   └── styles.css
└── src
    └── styles.css

error log:

https://pastebin.com/tctmPVpU

Body:
I've experienced this issue previously and fixed it by ensuring the relevant buildpacks were included.

https://devcenter.heroku.com/articles/buildpacks

Double check that you have the correct buildpacks for your application using this command:

heroku buildpacks

In my case I needed the ruby and node buildpacks, with the node pack preceeding the ruby one.


问:
Arrange columns of two different grids with gaps in line
How do I get the two grid cells "right" and "col" in a line below each other without adjusting the HTML?
Without gaps this is not a problem, but as soon as gaps are added, the columns are no longer in line.

*, *::before, *::after {
  box-sizing: border-box;
}

.OuterContainer {
  display: grid;
  column-gap: 32px;
  grid-template-columns: 1fr 3fr;
}

.Col4Grid {
    display: grid;
    column-gap: 32px;
    grid-template-columns: 1fr 1fr 1fr 1fr;
}

.Col {
  background-color: #e7e7e7;
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="OuterContainer">
  <div class="Col">
    left
  </div>
  <div class="Col">
    right
  </div>
</div>

<div class="Col4Grid">
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
</div></code>```

答:
Another more "dirty math" result. Just change the variable to whatever size you need.

*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
 --g-gap: 40px;
}

.OuterContainer {
  display: grid;
  column-gap: var(--g-gap);
  grid-template-columns: 1fr 3fr;
}

.Col4Grid {
  display: grid;
  column-gap: var(--g-gap);
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

.Col {
  background-color: #e7e7e7;
}

.Col4Grid .Col:first-child {
width: calc(100% + 1/2*var(--g-gap));
}

.Col4Grid .Col:not(:first-child) {
margin-left: calc(1/2*var(--g-gap));
}```
<pre class="snippet-code-html lang-html prettyprint-override"><code><div class="OuterContainer">
  <div class="Col">
    left
  </div>
  <div class="Col">
    right
  </div>
</div>

<div class="Col4Grid">
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
</div></code>```

This is of course not responsive (if you intend to use 100+px) and definitely not a good way to solve this, but I thought it is a funny way to tweak things!

Body:
How do I get the two grid cells "right" and "col" in a line below each other without adjusting the HTML?
Without gaps this is not a problem, but as soon as gaps are added, the columns are no longer in line.

*, *::before, *::after {
  box-sizing: border-box;
}

.OuterContainer {
  display: grid;
  column-gap: 32px;
  grid-template-columns: 1fr 3fr;
}

.Col4Grid {
    display: grid;
    column-gap: 32px;
    grid-template-columns: 1fr 1fr 1fr 1fr;
}

.Col {
  background-color: #e7e7e7;
}

    left

    right

col

col

col

col

Body:
Another more "dirty math" result. Just change the variable to whatever size you need.

*,
*::before,
*::after {
  box-sizing: border-box;
}

:root {
 --g-gap: 40px;
}

.OuterContainer {
  display: grid;
  column-gap: var(--g-gap);
  grid-template-columns: 1fr 3fr;
}

.Col4Grid {
  display: grid;
  column-gap: var(--g-gap);
  grid-template-columns: 1fr 1fr 1fr 1fr;
}

.Col {
  background-color: #e7e7e7;
}

.Col4Grid .Col:first-child {
width: calc(100% + 1/2*var(--g-gap));
}

.Col4Grid .Col:not(:first-child) {
margin-left: calc(1/2*var(--g-gap));
}

<div class="OuterContainer">
  <div class="Col">
    left
  </div>
  <div class="Col">
    right
  </div>
</div>

<div class="Col4Grid">
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
  <div class="Col">col</div>
</div>

This is of course not responsive (if you intend to use 100+px) and definitely not a good way to solve this, but I thought it is a funny way to tweak things!


问:
okta Angular 7 oktaAuth.isAuthenticated() is false even after successfully logging in
I am trying to work through this demo: https://developer.okta.com/blog/2018/12/04/angular-7-oidc-oauth2-pkce#upgrade-to-angular-7
This is one of a few tutorials which I have gone through and I keep on getting the same results

Even after I successfully log into Okta oktaAuth.isAuthenticated() is still set to false.

I know I am successfully logging in because the dashboard says I was successful and when I try to log in again I don't get redirected to the Sign In Page.

Here is my code:

app.component.html

```<code><h1>Welcome to {{ title }}!</h1>

<div *ngIf="isAuthenticated">
  <!-- <h2>Hi, {{user?.name}}!</h2> -->
  <button (click)="oktaAuth.logout()">Logout</button>
</div>

<div *ngIf="!isAuthenticated">
  <button (click)="oktaAuth.loginRedirect()">Login</button>
</div>

<router-outlet></router-outlet>
</code>```

app.component.ts

```<code>import { Component, OnInit } from '@angular/core';
import { OktaAuthService, UserClaims } from '@okta/okta-angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'ng-secure';
  isAuthenticated: boolean;
  email: string;

  constructor(public oktaAuth: OktaAuthService) {
  }

  async ngOnInit() {
    this.isAuthenticated = await this.oktaAuth.isAuthenticated();
           // Subscribe to authentication state changes
    this.oktaAuth.$authenticationState.subscribe( async(isAuthenticated: boolean)  => {
      this.isAuthenticated = isAuthenticated;
              });
  }
}
</code>```

app.module.ts

```<code>import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { HttpClientModule } from '@angular/common/http';
//import { OAuthModule } from 'angular-oauth2-oidc';

import { OktaAuthModule } from '@okta/okta-angular';

const config = {
  issuer: 'https://dev-xxxxxx.oktapreview.com/oauth2/default',
  redirectUri: window.location.origin + '/implicit/callback',
  clientId: 'Correct Client Id'
};

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    //OAuthModule.forRoot()
    OktaAuthModule.initAuth(config)

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
</code>```

app-routing.module.ts

```<code>import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { OktaCallbackComponent } from '@okta/okta-angular';

const routes: Routes = [
  {
    path: 'implicit/callback',
    component: OktaCallbackComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
</code>```

Is there another flag besides oktaAuth.isAuthenticated() to indicate that I am successfully logged in?

Thanks for your help.

I was able to get the okta-hosted-login example running which is provided by okta. However, this app is in Angular 5.

One thing I found interesting is if I try to log in using my Angular 7 app, I get the following error message:

Access to XMLHttpRequest at 'https://dev-979343.oktapreview.com/oauth2/default/.well-known/openid-configuration' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I don't get this CORS error when I ues the okta-hosted-login Angular 5

答:
For me it was that this.oktaAuth.tokenManager that I was calling .get("accessToken") on didn't have an accessToken property yet because that is added in the handleAuthentication() method that does

```<code>this.oktaAuth.tokenManager.add(
      "accessToken",
      tokenContainer.tokens.accessToken as AccessToken
    );
</code>```

Which wasn't being called by default as part of the login method, it was only called with the /callback route. And when I tried to call /callback directly I didn't have the token appended to the request so it was failing as well. So just make sure you add accessToken to the object before you call isAuthenticated()

I was working off of this example: https://developer.okta.com/code/angular/okta_angular_auth_js/ from developer.okta.com

Body:
I am trying to work through this demo: https://developer.okta.com/blog/2018/12/04/angular-7-oidc-oauth2-pkce#upgrade-to-angular-7
This is one of a few tutorials which I have gone through and I keep on getting the same results

Even after I successfully log into Okta oktaAuth.isAuthenticated() is still set to false.

I know I am successfully logging in because the dashboard says I was successful and when I try to log in again I don't get redirected to the Sign In Page.

Here is my code:

app.component.html

Welcome to {{ title }}!

  <button (click)="oktaAuth.logout()">Logout</button>

  <button (click)="oktaAuth.loginRedirect()">Login</button>

<router-outlet></router-outlet>

app.component.ts

import { Component, OnInit } from '@angular/core';
import { OktaAuthService, UserClaims } from '@okta/okta-angular';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
  title = 'ng-secure';
  isAuthenticated: boolean;
  email: string;

  constructor(public oktaAuth: OktaAuthService) {
  }

  async ngOnInit() {
    this.isAuthenticated = await this.oktaAuth.isAuthenticated();
           // Subscribe to authentication state changes
    this.oktaAuth.$authenticationState.subscribe( async(isAuthenticated: boolean)  => {
      this.isAuthenticated = isAuthenticated;
              });
  }
}

app.module.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { HttpClientModule } from '@angular/common/http';
//import { OAuthModule } from 'angular-oauth2-oidc';

import { OktaAuthModule } from '@okta/okta-angular';

const config = {
  issuer: 'https://dev-xxxxxx.oktapreview.com/oauth2/default',
  redirectUri: window.location.origin + '/implicit/callback',
  clientId: 'Correct Client Id'
};

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    //OAuthModule.forRoot()
    OktaAuthModule.initAuth(config)

  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app-routing.module.ts

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { OktaCallbackComponent } from '@okta/okta-angular';

const routes: Routes = [
  {
    path: 'implicit/callback',
    component: OktaCallbackComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Is there another flag besides oktaAuth.isAuthenticated() to indicate that I am successfully logged in?

Thanks for your help.

I was able to get the okta-hosted-login example running which is provided by okta. However, this app is in Angular 5.

One thing I found interesting is if I try to log in using my Angular 7 app, I get the following error message:

Access to XMLHttpRequest at 'https://dev-979343.oktapreview.com/oauth2/default/.well-known/openid-configuration' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

I don't get this CORS error when I ues the okta-hosted-login Angular 5

Body:
For me it was that this.oktaAuth.tokenManager that I was calling .get("accessToken") on didn't have an accessToken property yet because that is added in the handleAuthentication() method that does

this.oktaAuth.tokenManager.add(
      "accessToken",
      tokenContainer.tokens.accessToken as AccessToken
    );

Which wasn't being called by default as part of the login method, it was only called with the /callback route. And when I tried to call /callback directly I didn't have the token appended to the request so it was failing as well. So just make sure you add accessToken to the object before you call isAuthenticated()

I was working off of this example: https://developer.okta.com/code/angular/okta_angular_auth_js/ from developer.okta.com


问:
Reading values from test fixture Cypress
I'm new to Cypress and started playing around with fixtures.I'm trying to read values from a JSON file and then assert the values in a test.

Here is my code

```<code>it('Fixture test' ,() => {
    cy.fixture('AllNotificationStates').then(notifications => {
        for(let n in notifications) {
            cy.intercept('GET', '**/api', { fixture: 'AllNotificationStates.json' });

            cy.wrap(notifications[n])
            .should('be.an', 'object')
            .and('contain', {
                rowId: 1,
                streamId: "33e24004-04ff-4c44-8d59-c8752b0f43d7",
                notificationStatus: "Sent",
              });
        }
    });
})
</code>```

What this does is assert that the properties within the JSON file match the values I expect. What I'm trying to do is read the values from the fixture file save them to an object and then assert them in my test. So for example the property rowId in the contain should not be hard coded but read from the fixture file.

Edit here is my JSON file:

```<code>[
    {
      "rowId": 1,
      "streamId": "33e24004-04ff-4c44-8d59-c8752b0f43d7",
      "notificationStatus": "Sent",
      "details": {
        "name": "Notification",
        "createdTime": "2022-02-07T11:59:15.423Z",
        "createdBy": "test@test.com",
      }
]
</code>```

答:
You can save the fixture file to access them later in the same test.

```<code>it('Fixture test' ,() => {
    cy.fixture('AllNotificationStates').then(notifications => {
        // all your fixture checks
        }
      .as('fixtureAllNotStates')

    // some other test code

    cy.get('@fixtureAllNotStates').then ( () => {
       // some checks with fixture data
    });
})
</code>```

You can also call the fixture in beforeEach() for it to be used across multiple it blocks. This is a good reference for doing that

Body:
I'm new to Cypress and started playing around with fixtures.I'm trying to read values from a JSON file and then assert the values in a test.

Here is my code

it('Fixture test' ,() => {
    cy.fixture('AllNotificationStates').then(notifications => {
        for(let n in notifications) {
            cy.intercept('GET', '**/api', { fixture: 'AllNotificationStates.json' });

            cy.wrap(notifications[n])
            .should('be.an', 'object')
            .and('contain', {
                rowId: 1,
                streamId: "33e24004-04ff-4c44-8d59-c8752b0f43d7",
                notificationStatus: "Sent",
              });
        }
    });
})

What this does is assert that the properties within the JSON file match the values I expect. What I'm trying to do is read the values from the fixture file save them to an object and then assert them in my test. So for example the property rowId in the contain should not be hard coded but read from the fixture file.

Edit here is my JSON file:

[
    {
      "rowId": 1,
      "streamId": "33e24004-04ff-4c44-8d59-c8752b0f43d7",
      "notificationStatus": "Sent",
      "details": {
        "name": "Notification",
        "createdTime": "2022-02-07T11:59:15.423Z",
        "createdBy": "test@test.com",
      }
]

Body:
You can save the fixture file to access them later in the same test.

it('Fixture test' ,() => {
    cy.fixture('AllNotificationStates').then(notifications => {
        // all your fixture checks
        }
      .as('fixtureAllNotStates')

    // some other test code

    cy.get('@fixtureAllNotStates').then ( () => {
       // some checks with fixture data
    });
})

You can also call the fixture in beforeEach() for it to be used across multiple it blocks. This is a good reference for doing that


问:
Python Immutability List in Tuple - Object or Value?
Can someone help me understand why the second comparison between z and c variables resolve as False?

```<code>t = [1, 2, 3]
h = t
print(id(h), " ", id(t))
print(h is t)

x = ('bla', t)
y = ('bla', t)

z, c = str(x[1]), str(y[1])

print(id(z), " ", id(c))
print(z is c)
</code>```

My initial impression is that x[1] and y[1] would be pointing to the same reference since we're directly assigning that index of the tuples to the t variable. Does this mean Python is passing in the value of t rather than the object of the variable? Why does h is t evaluate to True but z is c evaluate to false? *** scratches head ***

答:
Immutability of a string is a necessary but not sufficient condition for having identical strings share the same object.  There is some overhead in looking up a string to see if it already exists, so most of the time Python doesn't bother.  It does provide a facility for interned strings so you can do it yourself if you want.

```<code>>>> import sys
>>> str(0) is str(0)
False
>>> sys.intern(str(0)) is sys.intern(str(0))
True
</code>```

Body:
Can someone help me understand why the second comparison between z and c variables resolve as False?

t = [1, 2, 3]
h = t
print(id(h), " ", id(t))
print(h is t)

x = ('bla', t)
y = ('bla', t)

z, c = str(x[1]), str(y[1])

print(id(z), " ", id(c))
print(z is c)

My initial impression is that x[1] and y[1] would be pointing to the same reference since we're directly assigning that index of the tuples to the t variable. Does this mean Python is passing in the value of t rather than the object of the variable? Why does h is t evaluate to True but z is c evaluate to false? *** scratches head ***

Body:
Immutability of a string is a necessary but not sufficient condition for having identical strings share the same object.  There is some overhead in looking up a string to see if it already exists, so most of the time Python doesn't bother.  It does provide a facility for interned strings so you can do it yourself if you want.

>>> import sys
>>> str(0) is str(0)
False
>>> sys.intern(str(0)) is sys.intern(str(0))
True


问:
Realtime Database permission denied (swift)
I'm trying to know if the player is already in a game or not but I'm completely new to the database programming. I keep getting this error

2022-02-07 17:32:51.787097+0100 Troeven2.0[64029:2674017] 7.10.0 - [Firebase/Database][I-RDB038012] Listener at / (and here the correct! user id of the current user) failed: permission_denied

update** and the error handler returning:

Error Domain=com.firebase Code=1 "Permission Denied" UserInfo={NSLocalizedDescription=Permission Denied}

**

I find this rather weird as the user has full rights how I see it to write and read his own data, rules:

```<code>{
  "rules": {
    "users": {
      ".read": "auth.uid != null",
      ".write": "auth.uid != null",
      "$uid": {
        ".write": "$uid == auth.uid"
      }
    }
  }
}
</code>```

my data structure is as follows:

and my code that I use to acces is this:

```<code>func checkIfInGame(completionHandler: @escaping (_ completionHandler: Bool) -> Void) {
    let currentUserID = Auth.auth().currentUser?.uid
    let ref = Database.database().reference().child(currentUserID!).child("gameInfo")

    ref.observe(.value , with: { (snapshot) in
        if let directory = snapshot.value as? [String: Any] {
            let gameID = directory["gameID"] as! String
            let isInGame = directory["inGame"] as! String
            var flag = false
            if isInGame == "yes" {
                flag = true
            }
            completionHandler(flag)
        }
    }) { (error) in
        print("error checking in game")
        completionHandler(false)
    }
}
</code>```

it's also maybe handy to know that my code immediately prints the error "error checking in game"
any help and time is really appreciated!

答:
Silly mistake that wasted my day: I did not go into child("users") hence no permission was granted. I also switched to getData since I only needed the data once when asked....</p>
```<code>func checkIfInGame(completionHandler: @escaping (_ completionHandler: Bool) -> Void) {
    guard let currentUserID = currentUser?.uid else {return}
    let ref = Database.database().reference().child("users").child(currentUserID)

    ref.child("gameInfo/inGame").getData(completion:  { error, snapshot in
        guard error == nil else {
            print(error!.localizedDescription)
            return;
        }
        let test = snapshot.value as? String ?? "no";

        print(test)
    })
}
</code>```

Body:
I'm trying to know if the player is already in a game or not but I'm completely new to the database programming. I keep getting this error

2022-02-07 17:32:51.787097+0100 Troeven2.0[64029:2674017] 7.10.0 - [Firebase/Database][I-RDB038012] Listener at / (and here the correct! user id of the current user) failed: permission_denied

update** and the error handler returning:

Error Domain=com.firebase Code=1 "Permission Denied" UserInfo={NSLocalizedDescription=Permission Denied}

**

I find this rather weird as the user has full rights how I see it to write and read his own data, rules:

{
  "rules": {
    "users": {
      ".read": "auth.uid != null",
      ".write": "auth.uid != null",
      "$uid": {
        ".write": "$uid == auth.uid"
      }
    }
  }
}

my data structure is as follows:

and my code that I use to acces is this:

func checkIfInGame(completionHandler: @escaping (_ completionHandler: Bool) -> Void) {
    let currentUserID = Auth.auth().currentUser?.uid
    let ref = Database.database().reference().child(currentUserID!).child("gameInfo")

    ref.observe(.value , with: { (snapshot) in
        if let directory = snapshot.value as? [String: Any] {
            let gameID = directory["gameID"] as! String
            let isInGame = directory["inGame"] as! String
            var flag = false
            if isInGame == "yes" {
                flag = true
            }
            completionHandler(flag)
        }
    }) { (error) in
        print("error checking in game")
        completionHandler(false)
    }
}

it's also maybe handy to know that my code immediately prints the error "error checking in game"
any help and time is really appreciated!

Body:
Silly mistake that wasted my day: I did not go into child("users") hence no permission was granted. I also switched to getData since I only needed the data once when asked....

func checkIfInGame(completionHandler: @escaping (_ completionHandler: Bool) -> Void) {
    guard let currentUserID = currentUser?.uid else {return}
    let ref = Database.database().reference().child("users").child(currentUserID)

    ref.child("gameInfo/inGame").getData(completion:  { error, snapshot in
        guard error == nil else {
            print(error!.localizedDescription)
            return;
        }
        let test = snapshot.value as? String ?? "no";

        print(test)
    })
}


问:
Virtual Trading Platform with Django Rest Framework (Good Idea)?
Trading application relies on many requests is it advisable to build the API backend with Django rest framework with scalability in mind? Any suggestions would be great.</p>

答: Use graphql. It is a very powerful API system. For Django there is this library called Graphene-django. Here is the link  https://docs.graphene-python.org/projects/django/en/latest/</p>


问:
Doctrine: calculating datetime difference
How can i calculate the difference between datetime column and now (for example 'created_at' and NOW()) in Doctrine?

I Googled it alot and couldn't find an answer..

Thanks in advance!

答:
try
$query -> select(DATE_DIFF(CURRENT_DATE(), datetime column))

DQL dont use now() sql function, they use CURRENT_DATE() instead


问:
Update application in already scaled out App Service
I'm generally confident in Azure App Service, however I can't find good documentation on how exactly Azure serves my new application if I deployed to an already scaled out App Service.

Say I have an app running and scaled to 5 instances (manually or auto scale, doesn't matter).

I now deploy a new version without staging slots. Directly into production.

How does Azure handle the scaled units now? Will new workers be warmed up and provisioned before my new application goes 'live'? Will there temporarily be 10 workers running my app?
Could it theoretically happen that 2/5 workers run the new version while 3/5 run the old one (for some time)?

Maybe I'm overseeing something or I'm thinking too complicated.

The only documentation I found was this web app architecture post. Still, it doesn't really answer my question.

答: Since Web Apps use a shared storage that is mapped to all five worker instances, if you deploy without using slots the content is updated on the shared storage and your app will restart to serve the updated application. All 5 instances will restart at the same time. This restart will cause your app experience some down time while it restarts</p>